diff --git a/frontend/src/lib/components/HandwriteCanvas.svelte b/frontend/src/lib/components/HandwriteCanvas.svelte index 3d376e5..d8db44c 100644 --- a/frontend/src/lib/components/HandwriteCanvas.svelte +++ b/frontend/src/lib/components/HandwriteCanvas.svelte @@ -32,6 +32,10 @@ size?: number; refW?: number; refH?: number; + // mouse stroke 는 pressure 정보 없음 (항상 0.5 fallback) → 굵기 변화 0. + // 그 경우 perfect-freehand 의 속도 기반 simulatePressure 사용 = 빠른 stroke + // 가늘게, 느린 stroke 굵게. Pencil 은 실제 pressure 사용. + simPressure?: boolean; _path2d?: Path2D; }; export type StrokesJson = { version: 1; strokes: Stroke[] }; @@ -118,13 +122,14 @@ // Path2D 등 런타임 캐시 (`_` prefix) 제외하고 직렬화. refW/refH 는 그렸을 시점의 // cssWidth/cssHeight — 다른 환경 (창 크기 다른 데스크톱, 모바일 등) 에서 load 시 // 비례 보정에 사용. 없으면 load 시점의 cssWidth/cssHeight 가 기준이 됨. - function serializableStrokes(): Pick[] { + function serializableStrokes(): Pick[] { return strokes.map((s) => ({ id: s.id, points: s.points, size: s.size, refW: s.refW, refH: s.refH, + simPressure: s.simPressure, })); } // backup 은 stroke 완료마다 호출되지만 실제 sync I/O (JSON.stringify + localStorage @@ -214,13 +219,14 @@ if (!path) { const outline = getStroke(pts, { size, - // thinning 0.55 — 압력 변동에 stroke 폭 큰 변동. 종이 만년필 reference 의 - // 5:1 굵기 차이를 부분적으로 재현 (MIN_PRESSURE 0.25 floor 와 조합 시 실제 - // 비율 약 2.4:1). Notability felt 의 핵심 = 압력에 따른 큰 굵기 차이. thinning: 0.55, smoothing: 0.99, streamline: 0.75, - simulatePressure: false, + // simulatePressure: true 항상. Apple Pencil 도 일부 iPadOS 빌드에서 실제 + // pressure 가 PointerEvent 에 정상 도달 안 하거나 일정 → 굵기 변화 0. + // 속도 기반 시뮬 (점 간 거리로 자동 추정) 이 더 robust + Notability 도 속도 + // 기반 felt. 빠른 stroke = 가늘게, 천천히 = 굵게. + simulatePressure: true, last: !isInflight, // cap: false — stroke 끝의 round cap 이 짧은 stroke 에선 dot 처럼 보이는 // 회귀. taper 가 stroke 끝을 자연스럽게 마무리하므로 cap 불필요. @@ -481,6 +487,9 @@ size: effectiveSize, refW: cssWidth, refH: cssHeight, + // pen 외 (mouse / touch) 는 속도 기반 시뮬. pressure 정보 없거나 무시되는 경우 + // 굵기 변화 보장. + simPressure: e.pointerType !== 'pen', }; scheduleRedraw(); }