feat(study): Notability 같은 미세한 굵기 변화 — pressure EMA + thinning 0.15

사용자 요청: stroke 굵기가 너무 일정해서 단조로움. Notability 처럼 살짝 압력에 따라
변화 있으면 좋겠다.

이전 thinning 0.18 + PRESSURE_SMOOTH_RATE 5% 조합은 점 간 5% 즉시 변동 가능 →
누적 시 들쭉날쭉. thinning 0 으로 회귀했었음.

Fix:
- Pressure smoothing 알고리즘 변경: rate-limit (±5%) → EMA (alpha 0.15).
  새 값 15% + 이전 값 85% 가중. 잡음/덜컥 변동 제거하면서도 자연스러운 흐름.
- thinning 0 → 0.15. pressure 변화에 stroke 폭 ±15% 반응.
- EMA + thinning 조합 → "부드러운 흐름에 따른 자연스러운 굵기 변화". 흔들림 없음.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-04-27 15:07:29 +09:00
parent 8a65dfd909
commit 084b85158b
@@ -214,8 +214,9 @@
if (!path) {
const outline = getStroke(pts, {
size,
// thinning 0 — pressure 변동에 stroke 폭 영향 안 받음. 흔들림 1차 차단.
thinning: 0,
// thinning 0.15 — pressure 변동에 stroke 폭 ±15% 반응. EMA 로 부드럽게
// smooth 된 pressure 와 조합 → Notability 같은 자연스러운 굵기 흐름.
thinning: 0.15,
// smoothing 0.99 — 점 간 보간 사실상 최대.
smoothing: 0.99,
// streamline 0.86 — input lazy 강하게. 손떨림 보정 + 부드러움. 0.9 이상은 lag.
@@ -336,13 +337,12 @@
// 점 사이 거리가 너무 멀면 중간 점 보간 — 빠른 stroke 의 sparse point 점선 방지.
// iPad 60Hz pointermove + 빠른 펜 이동 시 점 간격이 16~30px 가 될 수 있음.
const MAX_GAP_PX = 8;
// pressure 변동 limit — 만년필 효과: 약한 압력에도 부드럽게, 점 간 압력 차이가
// 너무 크면 stroke 폭이 들쭉날쭉해짐. 한 점당 5% 이내로만 변동.
const PRESSURE_SMOOTH_RATE = 0.05;
// pressure EMA — 점 간 pressure 변동을 *지수 이동 평균* 으로 부드럽게.
// alpha 0.15 = 새 값 15% + 이전 값 85% 가중. 잡음/덜컥 변동 제거 + Notability
// 같은 자연스러운 흐름. thinning=0.15 와 조합 시 stroke 굵기가 부드럽게 변함.
const PRESSURE_EMA_ALPHA = 0.15;
function smoothPressure(prev: number, current: number): number {
const dp = current - prev;
if (Math.abs(dp) <= PRESSURE_SMOOTH_RATE) return current;
return prev + Math.sign(dp) * PRESSURE_SMOOTH_RATE;
return prev + (current - prev) * PRESSURE_EMA_ALPHA;
}
function pushPointWithInterp(target: Stroke, x: number, y: number, p: number) {
const last = target.points[target.points.length - 1];