Skip to content

Commit 9b25a20

Browse files
committed
refactor: 메모이제이션 리팩토링
1 parent a7243f1 commit 9b25a20

File tree

8 files changed

+364
-252
lines changed

8 files changed

+364
-252
lines changed

src/components/Accordion/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef, useState } from 'react';
1+
import React, { useCallback, useRef, useState } from 'react';
22
import * as S from './styled';
33
import { arrowBottom, arrowTop } from '@assets/icons';
44
import Icon from '../../components/Icon';
@@ -13,7 +13,7 @@ const Accordion = ({ title, children, maxHeight = 200 }: AccordionProps) => {
1313
const panelRef = useRef<HTMLDivElement>(null);
1414
const [isOpenPanel, setIsOpenPanel] = useState(false);
1515

16-
const handleToggle = () => {
16+
const handleToggle = useCallback(() => {
1717
setIsOpenPanel(!isOpenPanel);
1818

1919
if (!panelRef.current) return;
@@ -26,7 +26,7 @@ const Accordion = ({ title, children, maxHeight = 200 }: AccordionProps) => {
2626
if (!panelRef.current) return;
2727
panelRef.current.style.overflow = 'visible';
2828
}, 300);
29-
};
29+
}, [isOpenPanel]);
3030

3131
return (
3232
<S.AccordionWrapper>

src/components/Canvas/index.tsx

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import useDragAndDropText from '../../hooks/useDragAndDropText';
2-
import React, { useEffect } from 'react';
2+
import React, { useCallback, useEffect } from 'react';
33
import { CanvasStateWithColors } from '../../types/canvas';
44
import * as S from './styled';
55

@@ -19,6 +19,7 @@ const Canvas = React.forwardRef(({ canvasState }: CanvasProps, ref: any) => {
1919
fontFamily,
2020
angle,
2121
isBlur,
22+
textAlign,
2223
isBlockEvent,
2324
bgColor,
2425
fontColor,
@@ -44,30 +45,51 @@ const Canvas = React.forwardRef(({ canvasState }: CanvasProps, ref: any) => {
4445
return strokeObj[fontStrokeType];
4546
};
4647

47-
const getMultiLinePosition = (
48-
linesLength: number,
49-
lineHeight: number,
50-
idx: number
51-
) => {
52-
const { offsetX, offsetY } = dragAndDropTextData;
53-
const centerX = +canvasWidth / 2;
54-
const centerY = +canvasHeight / 2;
55-
56-
const x = offsetX ? offsetX : centerX;
57-
const y = offsetY
58-
? offsetY - ((linesLength - 1) * lineHeight) / 2 + idx * lineHeight
59-
: centerY - ((linesLength - 1) * lineHeight) / 2 + idx * lineHeight;
48+
const getCenterX = useCallback(
49+
(lineMaxWidth: number) => {
50+
switch (textAlign) {
51+
case 'center':
52+
return +canvasWidth / 2;
53+
case 'end':
54+
return +canvasWidth / 2 + lineMaxWidth / 2;
55+
default:
56+
return +canvasWidth / 2 + (lineMaxWidth / 2) * -1;
57+
}
58+
},
59+
[textAlign, canvasWidth]
60+
);
6061

61-
return { x, y };
62-
};
62+
const getMultiLinePosition = useCallback(
63+
(
64+
linesLength: number,
65+
lineHeight: number,
66+
lineMaxWidth: number,
67+
idx: number
68+
) => {
69+
const { offsetX, offsetY } = dragAndDropTextData;
70+
const centerY = +canvasHeight / 2;
71+
const centerX = getCenterX(lineMaxWidth);
72+
73+
const x = offsetX ? offsetX : centerX;
74+
const y = offsetY
75+
? offsetY - ((linesLength - 1) * lineHeight) / 2 + idx * lineHeight
76+
: centerY - ((linesLength - 1) * lineHeight) / 2 + idx * lineHeight;
77+
78+
return { x, y };
79+
},
80+
[dragAndDropTextData, canvasHeight]
81+
);
6382

64-
const setFontStroke = (ctx: CanvasRenderingContext2D, line: string) => {
65-
if (fontStrokeType === 'None') return;
83+
const setFontStroke = useCallback(
84+
(ctx: CanvasRenderingContext2D, line: string) => {
85+
if (fontStrokeType === 'None') return;
6686

67-
ctx.lineWidth = getLineWidthByStrokeType();
68-
ctx.strokeStyle = `${strokeColor.hex}`;
69-
ctx.strokeText(line, 0, 0);
70-
};
87+
ctx.lineWidth = getLineWidthByStrokeType();
88+
ctx.strokeStyle = `${strokeColor.hex}`;
89+
ctx.strokeText(line, 0, 0);
90+
},
91+
[fontStrokeType, strokeColor]
92+
);
7193

7294
const rotateCanvas = (ctx: CanvasRenderingContext2D) => {
7395
const { offsetX, offsetY } = dragAndDropTextData;
@@ -87,9 +109,19 @@ const Canvas = React.forwardRef(({ canvasState }: CanvasProps, ref: any) => {
87109
) => {
88110
const size = +fontSize.replace('px', '');
89111
const fontLineHeight = size + +lineHeight;
112+
let lineMaxWidth = 0;
113+
114+
lines.forEach((line) => {
115+
lineMaxWidth = Math.max(lineMaxWidth, ctx.measureText(line).width);
116+
});
90117

91118
lines.forEach((line, idx) => {
92-
const { x, y } = getMultiLinePosition(lines.length, fontLineHeight, idx);
119+
const { x, y } = getMultiLinePosition(
120+
lines.length,
121+
fontLineHeight,
122+
lineMaxWidth,
123+
idx
124+
);
93125

94126
ctx.save();
95127
ctx.translate(x, y);
@@ -107,7 +139,7 @@ const Canvas = React.forwardRef(({ canvasState }: CanvasProps, ref: any) => {
107139
const size = +fontSize.replace('px', '');
108140

109141
ctx.font = `${size}px ${fontFamily}`;
110-
ctx.textAlign = 'center';
142+
ctx.textAlign = textAlign;
111143
ctx.textBaseline = 'middle';
112144

113145
ctx.save();

src/components/ColorPicker/index.tsx

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
import React, { useEffect, useRef, useState } from 'react';
2-
import { ColorPickerWrapper } from './styled';
1+
import React, {
2+
CSSProperties,
3+
useCallback,
4+
useEffect,
5+
useMemo,
6+
useRef,
7+
useState,
8+
} from 'react';
39
import { Color, ColorPicker as PaletteColorPicker } from 'react-color-palette';
410
import { IconButton } from '../Icon/styled';
11+
import './style.css';
512

613
interface ColorPickerPickerProps {
714
children: React.ReactNode;
815
color: Color;
916
setColor: (color: Color) => void;
1017
toggleIsBlockEvent: () => void;
1118
}
19+
1220
const ColorPickerPicker = ({
1321
children,
1422
color,
@@ -18,21 +26,24 @@ const ColorPickerPicker = ({
1826
const [isOpenColorPicker, setIsOpenColorPicker] = useState(false);
1927
const colorRef = useRef<HTMLDivElement>(null);
2028

21-
const handleCloseColorPicker = (e: any) => {
22-
if (isOpenColorPicker) {
23-
if (colorRef && colorRef.current) {
24-
if (!colorRef.current.contains(e.target)) {
25-
setIsOpenColorPicker(false);
26-
toggleIsBlockEvent();
29+
const handleCloseColorPicker = useCallback(
30+
(e: any) => {
31+
if (isOpenColorPicker) {
32+
if (colorRef.current) {
33+
if (!colorRef.current.contains(e.target)) {
34+
setIsOpenColorPicker(false);
35+
toggleIsBlockEvent();
36+
}
2737
}
2838
}
29-
}
30-
};
39+
},
40+
[isOpenColorPicker, toggleIsBlockEvent]
41+
);
3142

32-
const handleOpenColorPicker = () => {
33-
setIsOpenColorPicker(!isOpenColorPicker);
43+
const handleOpenColorPicker = useCallback(() => {
44+
setIsOpenColorPicker((prev) => !prev);
3445
toggleIsBlockEvent();
35-
};
46+
}, [toggleIsBlockEvent]);
3647

3748
useEffect(() => {
3849
document.addEventListener('mousedown', handleCloseColorPicker);
@@ -42,16 +53,31 @@ const ColorPickerPicker = ({
4253
};
4354
}, [handleCloseColorPicker]);
4455

56+
const wrapperStyle: CSSProperties = useMemo(() => {
57+
return {
58+
position: 'relative',
59+
};
60+
}, []);
61+
62+
const colorPickerWrapperStyle: CSSProperties = useMemo(() => {
63+
return {
64+
position: 'absolute',
65+
left: '50%',
66+
bottom: '40px',
67+
transform: 'translateX(-50%)',
68+
};
69+
}, []);
70+
4571
return (
46-
<ColorPickerWrapper>
72+
<div style={wrapperStyle}>
4773
<IconButton
4874
isOpenColorPicker={isOpenColorPicker}
4975
onClick={handleOpenColorPicker}
5076
isBorder={true}>
5177
{children}
5278
</IconButton>
5379
{isOpenColorPicker && (
54-
<div ref={colorRef}>
80+
<div ref={colorRef} style={colorPickerWrapperStyle}>
5581
<PaletteColorPicker
5682
width={250}
5783
height={150}
@@ -63,7 +89,7 @@ const ColorPickerPicker = ({
6389
/>
6490
</div>
6591
)}
66-
</ColorPickerWrapper>
92+
</div>
6793
);
6894
};
6995

0 commit comments

Comments
 (0)