import { clamp, lerp } from "~/shared/general.utils"; export const linear = (progress: number): number => progress; export const ease = (progress: number): number => -(Math.cos(Math.PI * progress) - 1) / 2; export function useTween(ref: Ref, animation: (progress: number) => number, then: () => void) { let initial = ref.value, current = ref.value, end = ref.value, progress = 0, time = 0, animationFrame: number, stop = true, last = 0; function loop(t: DOMHighResTimeStamp) { const elapsed = t - last; progress = clamp(progress + elapsed, 0, time); last = t; const step = animation(clamp(progress / time, 0, 1)); current = lerp(initial, end, step); then(); if(progress < time && !stop) { animationFrame = requestAnimationFrame(loop); } else { progress = 0; stop = true; } } return { stop: () => { cancelAnimationFrame(animationFrame); stop = true; }, update: (target: number, duration: number) => { initial = current; time = duration + progress; end = target; ref.value = target; if(stop) { stop = false; last = performance.now(); loop(performance.now()); } }, refresh: () => { current = ref.value; }, current: () => { return current; }, }; }