Skip to content

Commit

Permalink
feat: Implements change color, line-width, pen-mode function (#39)
Browse files Browse the repository at this point in the history
* feat: Update canvas store about pensetting 'mode, color, lineWidth'

* feat: Update MainCanvas with penSetting

* feat: Create DrawingComponent and CanvasToolbar

* feat: Implements change color and line-width and pen-mode

* style: Change DrawingComponent to DrawingArea and Use button instead div for clickable element

* style: Renaming DrawingComponent to DrawingArea
  • Loading branch information
dbjoung authored Nov 12, 2024
1 parent 1dee9b2 commit 9dbd7a0
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 4 deletions.
53 changes: 53 additions & 0 deletions client/src/components/canvas/CanvasToolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { ChangeEvent } from 'react';
import { LINEWIDTH_VARIABLE, PENMODE } from '@/constants/canvasConstants';
import { useCanvasStore } from '@/stores/useCanvasStore';
import { CanvasStore, PenModeType } from '@/types/canvas.types';

const CV = ['#000', '#f257c9', '#e2f724', '#4eb4c2', '#d9d9d9'];
//임시 색상 코드

const CanvasToolBar = () => {
const lineWidth = useCanvasStore((state: CanvasStore) => state.penSetting.lineWidth);
const setPenSetting = useCanvasStore((state: CanvasStore) => state.action.setPenSetting);
const setPenMode = useCanvasStore((state: CanvasStore) => state.action.setPenMode);

const handleChangeToolColor = (colorNum: number) => {
setPenSetting({ colorNum });
};
const handleChangeLineWidth = (lineWidth: string) => {
setPenSetting({ lineWidth: Number(lineWidth) });
};
const handleChangeToolMode = (modeNum: PenModeType) => {
setPenMode(modeNum);
};

return (
<section>
<section>
{CV.map((color, i) => {
return (
<button key={i} className={`bg-canvas-${i} h-16 w-16`} onClick={() => handleChangeToolColor(i)}>
{color}
</button>
);
})}
</section>
<section>
<input
type="range"
min={LINEWIDTH_VARIABLE.MIN_WIDTH}
max={LINEWIDTH_VARIABLE.MAX_WIDTH}
step={LINEWIDTH_VARIABLE.STEP_WIDTH}
value={lineWidth}
onChange={(e: ChangeEvent<HTMLInputElement>) => handleChangeLineWidth(e.target.value)}
/>
</section>
<section>
<button onClick={() => handleChangeToolMode(PENMODE.PEN)}></button>
<button onClick={() => handleChangeToolMode(PENMODE.PAINTER)}>페인팅</button>
</section>
</section>
);
};

export default CanvasToolBar;
13 changes: 13 additions & 0 deletions client/src/components/canvas/DrawingArea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import CanvasToolBar from './CanvasToolbar';
import MainCanvas from './MainCanvas';

const DrawingArea = () => {
return (
<section>
<MainCanvas />
<CanvasToolBar />
</section>
);
};

export default DrawingArea;
16 changes: 13 additions & 3 deletions client/src/components/canvas/MainCanvas.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { useRef, TouchEvent as ReactTouchEvent, MouseEvent as ReactMouseEvent } from 'react';
import { PENMODE } from '@/constants/canvasConstants';
import { useCanvasStore } from '@/stores/useCanvasStore';
import { CanvasStore } from '@/types/canvas.types';

const CANVAS_SIZE_WIDTH = 640; //임시 사이즈
const CANVAS_SIZE_HEIGHT = 420;

const CV = ['#000', '#f257c9', '#e2f724', '#4eb4c2', '#d9d9d9'];
//임시 색상 배열

const getTouchPoint = (canvas: HTMLCanvasElement, e: TouchEvent) => {
const { clientX, clientY } = e.touches[0]; //뷰포트 기준
const { top, left } = canvas.getBoundingClientRect(); // 캔버스의 뷰포트 기준 위치
Expand All @@ -22,15 +26,19 @@ const getDrawPoint = (
else throw new Error('mouse 혹은 touch 이벤트가 아닙니다.');
};

export const MainCanvas = () => {
const MainCanvas = () => {
const mainCanvasRef = useRef<HTMLCanvasElement>(null);
const canDrawing = useCanvasStore((state: CanvasStore) => state.canDrawing);
const setCanDrawing = useCanvasStore((state: CanvasStore) => state.action.setCanDrawing);
const penSetting = useCanvasStore((state: CanvasStore) => state.penSetting);

const drawStartPath = (ctx: CanvasRenderingContext2D, drawX: number, drawY: number) => {
ctx.beginPath();
ctx.fillStyle = CV[penSetting.colorNum];
ctx.strokeStyle = CV[penSetting.colorNum];
ctx.lineWidth = penSetting.lineWidth;

ctx.arc(drawX, drawY, 2, 0, Math.PI * 2);
ctx.arc(drawX, drawY, penSetting.lineWidth / 2, 0, Math.PI * 2);
ctx.fill();

ctx.beginPath();
Expand All @@ -56,7 +64,7 @@ export const MainCanvas = () => {
};

const handleDrawingEvent = (e: ReactTouchEvent<HTMLCanvasElement> | ReactMouseEvent<HTMLCanvasElement>) => {
if (!canDrawing) return;
if (!canDrawing || penSetting.mode === PENMODE.PAINTER) return;
if (!mainCanvasRef.current) return;

const canvas = mainCanvasRef.current;
Expand Down Expand Up @@ -97,3 +105,5 @@ export const MainCanvas = () => {
</section>
);
};

export default MainCanvas;
10 changes: 10 additions & 0 deletions client/src/constants/canvasConstants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const PENMODE = {
PEN: 0,
PAINTER: 1,
};

export const LINEWIDTH_VARIABLE = {
MIN_WIDTH: 2,
MAX_WIDTH: 10,
STEP_WIDTH: 2,
};
14 changes: 13 additions & 1 deletion client/src/stores/useCanvasStore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { create } from 'zustand';
import { CanvasStore } from '@/types/canvas.types';
import { CanvasStore, SelectingPenOptions } from '@/types/canvas.types';

const canvasDefaultConfig = {
inkRemaining: 500,
Expand All @@ -17,5 +17,17 @@ export const useCanvasStore = create<CanvasStore>((set) => ({
setCanDrawing: (canDrawing: boolean) => {
set(() => ({ canDrawing }));
},
setPenSetting: (penSetting: SelectingPenOptions) => {
set((state) => {
const newPenSettingState = { ...state.penSetting, ...penSetting };
return { ...state, penSetting: newPenSettingState };
});
},
setPenMode: (mode: number) => {
set((state) => {
const newPenSettingState = { ...state.penSetting, mode };
return { ...state, penSetting: newPenSettingState };
});
},
},
}));
15 changes: 15 additions & 0 deletions client/src/types/canvas.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import { PENMODE } from '@/constants/canvasConstants';

interface PenOptions {
mode: number;
colorNum: number;
lineWidth: number; //짝수 단위가 좋음
}

export type SelectingPenOptions = Partial<PenOptions>;

export type PenModeType = (typeof PENMODE)[keyof typeof PENMODE];

export interface CanvasStore {
canDrawing: boolean;
penSetting: PenOptions;
action: {
setCanDrawing: (canDrawing: boolean) => void;
setPenSetting: (penSetting: SelectingPenOptions) => void;
setPenMode: (penMode: PenModeType) => void;
};
}

0 comments on commit 9dbd7a0

Please sign in to comment.