Skip to content

Commit

Permalink
Merge pull request #113 from UoaWDCC/VPS-060/change-speech-box-arrow
Browse files Browse the repository at this point in the history
Vps 060/change speech box arrow
  • Loading branch information
djos192 authored Aug 6, 2023
2 parents 90d0910 + 6b309a2 commit 1940737
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 73 deletions.
142 changes: 77 additions & 65 deletions frontend/src/components/SpeechboxArrow.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,88 @@
import React, { useEffect } from "react";
import Triangle from "components/Triangle";

const SpeechTextboxArrow = React.memo(({ borderWidth, setArrowWidth }) => {
const arrowHeight = 25; // px
const arrowWidth = 25; // px
const SpeechTextboxArrow = React.memo(
({ borderWidth, setArrowWidth, arrowLocation }) => {
const arrowHeight = 25; // px
const arrowWidth = 25; // px

/**
* The angle being calculated here is the one that is opposite the horizontal or vertical line in the arrow/triangle
* @returns {number} angle - in radians
*/
function calculateAngleInArrow() {
return Math.atan2(arrowHeight, arrowWidth);
}
/**
* The angle being calculated here is the one that is opposite the horizontal or vertical line in the arrow/triangle
* @returns {number} angle - in radians
*/
function calculateAngleInArrow() {
return Math.atan2(arrowHeight, arrowWidth);
}

/**
* The arrow is made of one or two triangles
* If there is a border on the component, then a 2nd larger triangle will be placed behind the 1st to imitate a border
* The difference in widths of these triangles has to be found so that the perpendicular distance between the two triangles is same as component border
*
* @returns {number} widthOffset - in px
*/
function calculateBorderTriangleWidth() {
const arrowAngle = calculateAngleInArrow();
return (
borderWidth +
arrowWidth +
borderWidth / Math.cos(Math.PI / 2 - arrowAngle)
);
}
/**
* The arrow is made of one or two triangles
* If there is a border on the component, then a 2nd larger triangle will be placed behind the 1st to imitate a border
* The difference in widths of these triangles has to be found so that the perpendicular distance between the two triangles is same as component border
*
* @returns {number} widthOffset - in px
*/
function calculateBorderTriangleWidth() {
const arrowAngle = calculateAngleInArrow();
return (
borderWidth +
arrowWidth +
borderWidth / Math.cos(Math.PI / 2 - arrowAngle)
);
}

/**
* same as width offset calculator but for height
*/
function calculateBorderTriangleHeight() {
const arrowAngle = calculateAngleInArrow();
return (
arrowHeight +
borderWidth / Math.sin(Math.PI / 2 - arrowAngle) +
borderWidth * Math.tan(arrowAngle)
);
}
/**
* same as width offset calculator but for height
*/
function calculateBorderTriangleHeight() {
const arrowAngle = calculateAngleInArrow();
return (
arrowHeight +
borderWidth / Math.sin(Math.PI / 2 - arrowAngle) +
borderWidth * Math.tan(arrowAngle)
);
}

const borderTriangleWidth = calculateBorderTriangleWidth();
const borderTriangleHeight = calculateBorderTriangleHeight();
useEffect(() => {
setArrowWidth(borderTriangleWidth);
}, []);

const borderTriangleWidth = calculateBorderTriangleWidth();
const borderTriangleHeight = calculateBorderTriangleHeight();
useEffect(() => {
setArrowWidth(borderTriangleWidth);
}, []);
const diffStyles = {
top: { margin: "marginBottom", rotation: 0, align: "flex-end" },
bottom: { margin: "marginTop", rotation: 180, align: "flex-start" },
left: { margin: "marginRight", rotation: 270, align: "flex-start" },
right: { margin: "marginLeft", rotation: 90, align: "flex-end" },
}[arrowLocation];

return (
<div
style={{
position: "relative",
height: borderTriangleHeight,
marginBottom: -borderWidth,
}}
>
{/* border (of arrow) triangle */}
<Triangle
triangleHeight={borderTriangleHeight}
triangleWidth={borderTriangleWidth}
colour="black"
/>
return (
<div
style={{
position: "relative",
height: borderTriangleHeight,
width: borderTriangleWidth,
[diffStyles.margin]: -borderWidth,
alignSelf: diffStyles.align,
transform: `rotate(${diffStyles.rotation}deg)`,
}}
>
{/* border (of arrow) triangle */}
<Triangle
triangleHeight={borderTriangleHeight}
triangleWidth={borderTriangleWidth}
colour="black"
/>

{/* arrow triangle */}
<Triangle
triangleHeight={arrowHeight}
triangleWidth={arrowWidth}
colour="white"
additionalStyles={{ marginRight: borderWidth }}
/>
</div>
);
});
{/* arrow triangle */}
<Triangle
triangleHeight={arrowHeight}
triangleWidth={arrowWidth}
colour="white"
additionalStyles={{ marginRight: borderWidth }}
/>
</div>
);
}
);

export default SpeechTextboxArrow;
2 changes: 1 addition & 1 deletion frontend/src/components/TimerComponent/Notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function Notification({ setTime, sceneTime }) {
variant="contained"
color="black"
onClick={handleClose}
style={{ "margin-left": "10%" }}
style={{ marginLeft: "10%" }}
>
Continue
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,26 @@ export default function SpeechTextPropertiesComponent({
<MenuItem value="white">White</MenuItem>
</Select>
</FormControl>

<FormControl fullWidth className={styles.componentProperty}>
<CustomInputLabel shrink>Arrow Location</CustomInputLabel>
<Select
className={styles.selectInput}
value={component.arrowLocation}
onChange={(event) =>
updateComponentProperty(
componentIndex,
"arrowLocation",
event.target.value
)
}
>
<MenuItem value="top">Top</MenuItem>
<MenuItem value="left">Left</MenuItem>
<MenuItem value="right">Right</MenuItem>
<MenuItem value="bottom">Bottom</MenuItem>
</Select>
</FormControl>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@ import useStyles from "./components.styles";

const borderWidth = 3.429; // px

/**
* @param {number} borderRadius
* @param {string} squareCorner
* @returns {string} borderRadius CSS value
*/
function formatRadius(borderRadius, squareCorner) {
const diffRadii = new Array(4).fill(`${borderRadius}px`);

const position = {
TopLeft: 0,
TopRight: 1,
BottomRight: 2,
BottomLeft: 3,
}[squareCorner];

diffRadii[position] = "0"; // this is the square corner

return diffRadii.join(" ");
}

/**
* This React component represents a speech text scene component
* @component
Expand All @@ -20,16 +40,34 @@ export default function SpeechTextComponent({ id, onClick, component }) {
const { defaultComponentStyling, speechTextComponentStyles } =
useStyles(component);
const [speechTextboxArrowWidth, setArrowWidth] = useState(null);

const context = useContext(AuthoringToolContext);
const textRef = context?.propertiesRefs?.text;

// style related values
const speechboxWidthOffset = 10;
const arrowLocation = component.arrowLocation || "right";
const arrowLocationStyles = {
top: { flexDirection: "column", squareCorner: "TopRight" },
bottom: {
flexDirection: "column-reverse",
squareCorner: "BottomLeft",
},
left: { flexDirection: "row", squareCorner: "TopLeft" },
right: {
flexDirection: "row-reverse",
squareCorner: "BottomRight",
},
}[arrowLocation];

return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
<div
className={defaultComponentStyling}
style={{
display: "flex",
flexDirection: "column",
minWidth: speechTextboxArrowWidth + 10, // speechbox slightly wider than arrow
flexDirection: arrowLocationStyles.flexDirection,
minWidth: speechTextboxArrowWidth + speechboxWidthOffset, // speechbox slightly wider than arrow
}}
onClick={onClick}
onDoubleClick={() => textRef?.current?.focus()}
Expand All @@ -38,14 +76,17 @@ export default function SpeechTextComponent({ id, onClick, component }) {
<SpeechTextboxArrow
borderWidth={borderWidth}
setArrowWidth={setArrowWidth}
arrowLocation={arrowLocation}
/>

<Typography
style={{
borderWidth,
flex: 1,
borderRadius: "10px",
borderTopRightRadius: 0,
borderRadius: formatRadius(
speechboxWidthOffset,
arrowLocationStyles.squareCorner
),
}}
className={speechTextComponentStyles}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ exports[`Add speech text component snapshot test 1`] = `
<div>
<div
class="makeStyles-defaultComponentStyling-5"
style="display: flex; flex-direction: column; min-width: 43.27833830537734px;"
style="display: flex; flex-direction: row-reverse; min-width: 43.27833830537734px;"
>
<div
style="position: relative; height: 33.278338305377346px; margin-bottom: -3.429px;"
style="position: relative; height: 33.278338305377346px; width: 33.27833830537734px; margin-left: -3.429px; align-self: flex-end; transform: rotate(90deg);"
>
<div
style="box-sizing: border-box; border-left: 33.27833830537734px solid transparent; border-bottom: 33.278338305377346px solid black; position: absolute; bottom: 0px; right: 0px;"
Expand All @@ -19,7 +19,7 @@ exports[`Add speech text component snapshot test 1`] = `
</div>
<p
class="MuiTypography-root makeStyles-speechTextComponentStyles-7 MuiTypography-body1"
style="border-width: 3.429px; flex: 1; border-radius: 10px; border-top-right-radius: 0;"
style="border-width: 3.429px; flex: 1; border-radius: 10px 10px 0 10px;"
>
default speech text
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ function addSpeechText(currentScene, setCurrentScene) {
top: 0, // as percentage
height: 10, // as percentage
width: 20, // as percentage
arrowLocation: "top",
id: v4(),
};

Expand Down

0 comments on commit 1940737

Please sign in to comment.