From 580f3ab72887708d331c163d69c404b20475ddad Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Mon, 27 Apr 2026 15:24:14 +0900 Subject: [PATCH] =?UTF-8?q?fix(study):=20=EC=9E=91=EC=9D=80=20=EA=B8=80?= =?UTF-8?q?=EC=9E=90=20stroke=20=EC=9D=B8=EC=8B=9D=20=E2=80=94=20streamlin?= =?UTF-8?q?e=20=EC=99=84=ED=99=94=20+=20taper=20=EC=A7=A7=EA=B2=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사용자 보고: 글자가 작아지면 제대로 인식 못 함 (스크린샷의 작은 "유" 가 부서져 보임). 원인: 1. streamline 0.86 = 입력 점이 펜 위치보다 lazy 하게 따라옴. 긴 stroke 에선 부드러움 이지만 짧은 stroke (작은 글자) 에선 lag 누적 > stroke 길이 → 펜이 떨어져도 stroke 가 못 따라감 → 부서진 dot 처럼 보임. 2. start.taper size*0.3 + end.taper size*0.5 = 짧은 stroke (length ≈ size × 1~2) 의 거의 전체가 taper 영역 → stroke 가 모두 가늘게 그려짐. Fix: - streamline 0.86 → 0.75. 부드러움 + 짧은 stroke 정확성 균형. - start.taper size*0.3 → 0.15. - end.taper size*0.5 → 0.3. 만년필 nib felt 는 유지 (taper 비율 그대로) 하되 영향 길이 줄임. Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/src/lib/components/HandwriteCanvas.svelte | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/frontend/src/lib/components/HandwriteCanvas.svelte b/frontend/src/lib/components/HandwriteCanvas.svelte index 13e421e..c62b3cd 100644 --- a/frontend/src/lib/components/HandwriteCanvas.svelte +++ b/frontend/src/lib/components/HandwriteCanvas.svelte @@ -216,14 +216,16 @@ size, thinning: 0.28, smoothing: 0.99, - streamline: 0.86, + // streamline 0.75 — 0.86 은 짧은 stroke (작은 글자) 에서 lag 누적으로 펜 + // 위치를 따라오지 못해 stroke 가 부서져 보임. 0.75 가 부드러움 + 짧은 + // stroke 정확성 균형. + streamline: 0.75, simulatePressure: false, last: !isInflight, - // 만년필 nib 효과: 시작은 짧게 가늘게 (nib 이 종이에 닿는 순간), 끝은 좀 - // 더 길게 가늘어짐 (nib 이 종이에서 떨어질 때). easing ease-out 으로 - // 빠르게 굵어졌다 천천히 안정 → Notability felt. - start: { cap: true, taper: size * 0.3, easing: (t) => t * (2 - t) }, - end: { cap: true, taper: size * 0.5, easing: (t) => t * (2 - t) }, + // taper 짧게 — 작은 글자 stroke (size × 1~2 길이) 에서 taper 영역이 전체를 + // 차지하지 않도록. nib felt 는 유지하되 짧은 stroke 도 명확히. + start: { cap: true, taper: size * 0.15, easing: (t) => t * (2 - t) }, + end: { cap: true, taper: size * 0.3, easing: (t) => t * (2 - t) }, }); if (outline.length < 2) return; path = new Path2D(getSvgPathFromStroke(outline));