From 66c6fb6189da94c1d5a893e0941ea7722ae4731a Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Mon, 27 Apr 2026 09:56:37 +0900 Subject: [PATCH] =?UTF-8?q?fix(study):=20stroke=20=EC=82=AC=EB=9D=BC?= =?UTF-8?q?=EC=A7=90=20=ED=95=B5=EC=8B=AC=20=EB=B2=84=EA=B7=B8=20+=20?= =?UTF-8?q?=EB=94=94=EB=B2=84=EA=B7=B8=20=ED=91=9C=EC=8B=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 원인: \$effect(initialStrokes 동기화) 가 strokes 도 의존성으로 추적함. 사용자가 펜으로 그린 후 strokes 변경 → effect 재실행 → 조건 "initialStrokes.strokes !== strokes" 가 true → strokes 를 옛 initialStrokes 값으로 되돌림 → 새 stroke 사라짐. 지우개 누르면 글자가 커지는 현상도 같은 effect 가 trigger 되며 strokes 가 옛 값으로 reset + canvas 비율 재계산이 겹쳐 발생. Fix: - \$effect 제거. 초기 strokes 는 \$state initial value 로 한 번만 set. 부모가 prop 새 값을 줘도 무시 (사용자 진행 stroke 우선). - traceText effect 는 명시적 prev 비교로만 redraw 트리거. - 디버그용 빨간 사각형 / 빨간 strokeStyle 제거. 정상 색 (--text) 복귀. --- .../src/lib/components/HandwriteCanvas.svelte | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/frontend/src/lib/components/HandwriteCanvas.svelte b/frontend/src/lib/components/HandwriteCanvas.svelte index ea0af62..0698719 100644 --- a/frontend/src/lib/components/HandwriteCanvas.svelte +++ b/frontend/src/lib/components/HandwriteCanvas.svelte @@ -117,20 +117,18 @@ redraw(); } - // ── render — 디버그 모드: stroke 빨강 + 굵게 + 좌상단 빨간 사각형 강제. - // 사용자 보고에 따라 격리: 빨간 사각형 보임 + 빨간 stroke 안 보임 → drawStroke 문제. - // 빨간 사각형도 안 보임 → redraw 미호출 / canvas 가려짐. + // ── render — 단순 ctx.stroke(). function drawStroke(ctx: CanvasRenderingContext2D, s: Stroke) { if (s.points.length === 0) return; ctx.lineCap = 'round'; ctx.lineJoin = 'round'; - ctx.lineWidth = 12; // 디버그: 충분히 굵게 - ctx.strokeStyle = '#ff3333'; // 디버그: 빨강 강제 - ctx.fillStyle = '#ff3333'; + ctx.lineWidth = baseSize; + ctx.strokeStyle = strokeColor; + ctx.fillStyle = strokeColor; if (s.points.length === 1) { const [x, y] = s.points[0]; ctx.beginPath(); - ctx.arc(x, y, 6, 0, Math.PI * 2); + ctx.arc(x, y, baseSize / 2, 0, Math.PI * 2); ctx.fill(); return; } @@ -160,11 +158,6 @@ if (!ctx) return; ctx.clearRect(0, 0, cssWidth, cssHeight); drawTraceBackground(ctx); - - // 디버그: 좌상단 빨간 사각형 (50x50). 보이면 redraw + canvas 정상 동작. - ctx.fillStyle = '#ff0000'; - ctx.fillRect(10, 10, 50, 50); - for (const s of strokes) { drawStroke(ctx, s); } @@ -404,17 +397,19 @@ } }); + // initialStrokes 동기화는 onMount 한 번만 (위에서 이미 처리). $effect 사용 시 + // strokes 도 의존성으로 추적되어 사용자가 stroke 추가하는 순간 옛 initialStrokes 로 + // 되돌아가는 버그 발생 → 펜 떼면 새 stroke 사라짐. + // 부모가 prop 으로 새 initialStrokes 를 보내도 무시 (사용자 진행 stroke 우선). + + // traceText 변경 시만 redraw 트리거 (의존성 명시 access). + let _prevTraceText = $state(traceText); $effect(() => { - if (initialStrokes && initialStrokes.strokes !== strokes) { - strokes = initialStrokes.strokes; - undoStack = []; + if (traceText !== _prevTraceText) { + _prevTraceText = traceText; redraw(); } }); - $effect(() => { - void traceText; - redraw(); - });