From b7058ba40bb9292a126a40e889c047c961593ee2 Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Mon, 27 Apr 2026 15:21:34 +0900 Subject: [PATCH] =?UTF-8?q?feat(study):=20Notability=20felt=20=E2=80=94=20?= =?UTF-8?q?start/end=20taper=20+=20ease-out?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사용자 보고: Notability 의 그 맛이 안 남. 만년필 nib 의 핵심 felt 누락. Notability 의 만년필 stroke 특징: - 시작 = nib 이 종이에 닿는 순간. 짧게 가늘게 시작. - 끝 = nib 이 종이에서 떨어짐. 좀 더 길게 가늘어짐. - ease-out 곡선: 빠르게 굵어졌다 천천히 안정. Fix: - start.taper: size * 0.3, easing: t * (2-t) (ease-out) - end.taper: size * 0.5, easing: t * (2-t) - cap: true 유지 (round 끝점) 이전에 taper 가 흔들림 원인이라 뺐었지만, 그건 thinning 0.18 + 보간 점 micro 변동 + EMA 와 겹친 회귀였음. 지금은 마디/흔들림 모두 차단됐으니 taper 안전하게 도입 가능. Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/src/lib/components/HandwriteCanvas.svelte | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/frontend/src/lib/components/HandwriteCanvas.svelte b/frontend/src/lib/components/HandwriteCanvas.svelte index 49aa600..13e421e 100644 --- a/frontend/src/lib/components/HandwriteCanvas.svelte +++ b/frontend/src/lib/components/HandwriteCanvas.svelte @@ -214,18 +214,16 @@ if (!path) { const outline = getStroke(pts, { size, - // thinning 0.28 — pressure 변동에 stroke 폭 ±28% 반응. MIN_PRESSURE 0.4 - // floor 와 조합하면 약한 pressure 에서도 stroke 가 충분히 보이고, 강한 - // pressure 에선 만년필 nib 같은 굵기 차이. thinning: 0.28, - // smoothing 0.99 — 점 간 보간 사실상 최대. smoothing: 0.99, - // streamline 0.86 — input lazy 강하게. 손떨림 보정 + 부드러움. 0.9 이상은 lag. streamline: 0.86, simulatePressure: false, last: !isInflight, - start: { cap: true, taper: 0 }, - end: { cap: true, taper: 0 }, + // 만년필 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) }, }); if (outline.length < 2) return; path = new Path2D(getSvgPathFromStroke(outline));