Skip to content

Commit

Permalink
Update text configs upon selecting a text
Browse files Browse the repository at this point in the history
  • Loading branch information
low-earth-orbit committed Sep 30, 2024
1 parent 1d23d2e commit 3fc4638
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 26 deletions.
19 changes: 15 additions & 4 deletions components/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ import {
updateSelectedTool,
} from "../redux/canvasSlice";
import { SHAPE_DEFAULT_HEIGHT, SHAPE_DEFAULT_WIDTH } from "./shapes/shapeUtils";
import { TEXT_DEFAULT_HEIGHT, TEXT_DEFAULT_WIDTH } from "./text/textUtils";
import {
getFontStyleStringFromTextStyleArray,
getTextDecorationStringFromTextStyleArray,
TEXT_DEFAULT_HEIGHT,
TEXT_DEFAULT_WIDTH,
} from "./text/textUtils";
import ShapePanel from "./toolbar/ShapePanel";
import TextPanel from "./toolbar/TextPanel";
import {
Expand Down Expand Up @@ -83,6 +88,9 @@ export default function Canvas() {
(state: RootState) => state.shape,
);

const { textSize, textStyle, textColor, textAlignment, lineSpacing } =
useSelector((state: RootState) => state.text);

const [isInProgress, setIsInProgress] = useState(false);
const [newObject, setNewObject] = useState<CanvasObjectType | null>(null); // new text/shape object to be added to the canvas

Expand Down Expand Up @@ -260,10 +268,13 @@ export default function Canvas() {
y: y,
width: TEXT_DEFAULT_WIDTH,
height: TEXT_DEFAULT_HEIGHT,
fill: strokeColor, // use strokeColor for fill for now
// strokeWidth not applied to text field for now
fill: textColor,
text: "Double click to edit.",
fontSize: 28,
fontSize: textSize,
align: textAlignment,
lineHeight: lineSpacing,
fontStyle: getFontStyleStringFromTextStyleArray(textStyle),
textDecoration: getTextDecorationStringFromTextStyleArray(textStyle),
fontFamily: "Arial",
};

Expand Down
25 changes: 24 additions & 1 deletion components/text/TextLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@ import { Layer } from "react-konva";
import { CanvasObjectType } from "../Canvas";
import TextField from "./TextField";
import { RootState } from "@/redux/store";
import { useSelector } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { updateCanvasObject } from "@/redux/canvasSlice";
import {
setLineSpacing,
setTextAlignment,
setTextColor,
setTextSize,
setTextStyle,
} from "@/redux/textSlice";
import { convertTextPropertiesToTextStyleArray } from "./textUtils";

type Props = {
objects: CanvasObjectType[];
Expand All @@ -24,6 +33,8 @@ export default function TextLayer({
onChange,
setSidePanelVisible,
}: Props) {
const dispatch = useDispatch();

const { selectedTool } = useSelector((state: RootState) => state.canvas);

const texts = [
Expand All @@ -46,6 +57,18 @@ export default function TextLayer({
setSidePanelVisible(true);

// update settings to match selected text's
dispatch(setTextSize(text.fontSize || 28));
dispatch(setTextColor(text.fill || "#000"));
dispatch(setTextAlignment(text.align || "left"));
dispatch(setLineSpacing(text.lineHeight || 1.5));
dispatch(
setTextStyle(
convertTextPropertiesToTextStyleArray(
text.fontStyle,
text.textDecoration,
),
),
);

// Update cursor style
const stage = e.target.getStage();
Expand Down
40 changes: 40 additions & 0 deletions components/text/textUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,43 @@ export const TEXT_DEFAULT_WIDTH = 200;
export const TEXT_DEFAULT_HEIGHT = 50;
export const TEXT_MIN_WIDTH = 5;
export const TEXT_MIN_HEIGHT = 5;

export function convertTextPropertiesToTextStyleArray(
fontStyle: string | undefined,
textDecoration: string | undefined,
): string[] {
let textStyle = [];
if (fontStyle?.includes("bold")) {
textStyle.push("bold");
}
if (fontStyle?.includes("italic")) {
textStyle.push("italic");
}
if (textDecoration?.includes("underline")) {
textStyle.push("underline");
}
return textStyle;
}

export function getFontStyleStringFromTextStyleArray(
textStyle: string[],
): string {
let fontStyle = "";
if (textStyle.includes("bold")) {
fontStyle += "bold";
}
if (textStyle.includes("italic")) {
fontStyle += " italic";
}
return fontStyle;
}

export function getTextDecorationStringFromTextStyleArray(
textStyle: string[],
): string {
let textDecoration = "";
if (textStyle.includes("underline")) {
textDecoration += "underline";
}
return textDecoration;
}
2 changes: 1 addition & 1 deletion components/toolbar/ShapePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export default function ShapePanel({
}}
aria-label="Border width"
onChange={(_, value) => setStrokeWidth(value as number)}
sx={{ flex: 1 }}
sx={{ flex: 1, mr: 2 }}
/>
</Box>
</Box>
Expand Down
24 changes: 10 additions & 14 deletions components/toolbar/TextPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ import {
setTextStyle,
} from "@/redux/textSlice";
import { updateCanvasObject } from "@/redux/canvasSlice";
import {
getFontStyleStringFromTextStyleArray,
getTextDecorationStringFromTextStyleArray,
} from "../text/textUtils";

type Props = {
onClose: () => void;
Expand All @@ -58,33 +62,25 @@ export default function TextPanel({
event: React.MouseEvent<HTMLElement>,
newStyle: string[],
) => {
console.log("newStyle = ", newStyle);
// update textStyle in redux store
dispatch(setTextStyle(newStyle));

// update selected object
// fontStyle (bold / italic)
let newFontStyle = "";
if (newStyle.includes("bold")) {
newFontStyle += "bold";
}
if (newStyle.includes("italic")) {
newFontStyle += " italic";
}
dispatch(
updateCanvasObject({
id: selectedObjectId,
updates: { fontStyle: newFontStyle },
updates: { fontStyle: getFontStyleStringFromTextStyleArray(newStyle) },
}),
);

// textDecoration (underline)
let newTextDecoration = "";
if (newStyle.includes("underline")) {
newTextDecoration += "underline";
}
dispatch(
updateCanvasObject({
id: selectedObjectId,
updates: { textDecoration: newTextDecoration },
updates: {
textDecoration: getTextDecorationStringFromTextStyleArray(newStyle),
},
}),
);
};
Expand Down
9 changes: 3 additions & 6 deletions redux/textSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ interface TextState {
textSize: number;
textStyle: string[];
textColor: string;
textAlignment: "left" | "center" | "right";
textAlignment: string;
lineSpacing: number;
}

const initialState: TextState = {
textSize: 16,
textSize: 28,
textStyle: [],
textColor: "#000000",
textAlignment: "left",
Expand All @@ -29,10 +29,7 @@ const textSlice = createSlice({
setTextColor: (state, action: PayloadAction<string>) => {
state.textColor = action.payload;
},
setTextAlignment: (
state,
action: PayloadAction<"left" | "center" | "right">,
) => {
setTextAlignment: (state, action: PayloadAction<string>) => {
state.textAlignment = action.payload;
},
setLineSpacing: (state, action: PayloadAction<number>) => {
Expand Down

0 comments on commit 3fc4638

Please sign in to comment.