snapping feedback animation
snap은 node 위치를 바꾸는 기능이지만, 사용자는 왜 위치가 보정됐는지도 알아야 합니다. guide animation은 그 설명 역할을 합니다.
guide animation state 코드
snap 결과와 guide 시각 효과를 분리하면 drag 반응성을 해치지 않습니다.
function createSnapGuideAnimation(guide) {
return {
id: crypto.randomUUID(),
guide,
startedAt: performance.now(),
holdMs: 180,
fadeMs: 120
};
}
function guideOpacity(animation, now) {
const elapsed = now - animation.startedAt;
if (elapsed < animation.holdMs) return 1;
return Math.max(0, 1 - (elapsed - animation.holdMs) / animation.fadeMs);
}
function pruneGuideAnimations(animations, now) {
return animations.filter((item) => guideOpacity(item, now) > 0);
}
feedback state
snap target found
guide fade in
node corrected
guide hold
guide fade out
실제 node position과 guide animation state는 분리합니다.
snap 결과와 visual guide를 함께 반환한다
function applySnapping(drag, candidates) {
let best = null;
for (const candidate of candidates) {
const distance = Math.abs(candidate.value - drag.value);
if (distance < 6 && (!best || distance < best.distance)) {
best = { ...candidate, distance };
}
}
if (!best) {
return { value: drag.value, guides: [] };
}
return {
value: best.value,
guides: [createSnapGuideAnimation(best.guide)]
};
}
snap은 위치 보정 결과와 시각 guide를 같이 만들어야 합니다. 하지만 guide animation은 document history에 들어가지 않는 transient UI state로 관리합니다.
오늘의 핵심
snap animation은 짧고 명확해야 합니다. drag를 방해하면 polish가 아니라 latency가 됩니다.