Skip to content

이징 함수(tween)

이징의 갈래가 일곱이고, 저마다 easeIneaseOut 꼴이 있습니다. 순수한 수식이라 DOM도, 자체 RAF 루프도 없습니다. 여러분의 애니메이션 프레임에서 지금 시각을 넣어 주면, 그 프레임이 써야 할 값을 돌려줍니다.

인자는 로버트 페너의 고전적인 관례를 따릅니다.

  • t: 지금 시각(얼마나 지났는지)
  • b: 시작 값
  • c: 값의 변화량(끝 값은 b + c)
  • d: 지속 시간

모든 함수가 안에서 t >= d일 때 값을 죄므로, 끝을 지나 불러도 범위 밖으로 외삽하지 않고 마지막 값을 돌려줍니다.

사용법

ts
import { cubic } from 'ranuts/utils';

const start = performance.now();
const tick = (now: number) => {
  const x = cubic.easeOut(now - start, 0, 300, 600); // 600ms 동안 0 → 300
  el.style.transform = `translateX(${x}px)`;
  if (now - start < 600) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);

쓸 수 있는 곡선

내보내는 이름곡선느낌
quad2차()가장 부드러운 가속. 무난한 기본값
cubic3차()quad보다 눈에 띄게 날렵합니다
quart4차(t⁴)힘찬 가속
quint5차(t⁵)매우 힘차고, 끝자락이 움직임의 인상을 좌우합니다
sine사인가장 부드러워 이징인지도 잘 느껴지지 않습니다
expo지수거의 멎어 있다가 갑자기 내달립니다
circ느리게 시작해 끝이 매우 갑작스럽습니다

API

내보내는 것들의 생김새는 모두 같습니다.

ts
interface SpeedType {
  easeIn: EasingFn;
  easeOut: EasingFn;
}

type EasingFn = (t: number, b: number, c: number, d: number) => number;

easeIn / easeOut

매개변수

매개변수설명타입기본값
t지난 시간number필수
b시작 값number필수
c값의 변화량(끝은 b + c)number필수
d지속 시간number필수

반환값

인자설명타입
value시각 t에서의 값number

참고

easeIn은 느리게 시작해 빨라지고, easeOut은 빠르게 시작해 느려집니다. 사용자의 동작에 응답하는 UI라면 대개 easeOut이 더 자연스럽게 읽힙니다. 먼저 머뭇거리지 않고 곧바로 움직여 자리를 잡기 때문입니다.

zhangxinxu/Tween에 감사드립니다.

MIT 라이선스로 배포됩니다.