UNPKG

@studiometa/js-toolkit

Version:

A set of useful little bits of JavaScript to boost your project! 🚀

97 lines (96 loc) • 2.69 kB
import { cubicBezier } from "@motionone/easing"; import { lerp, map, clamp01, damp, inertiaFinalValue } from "./math/index.js"; import { isDefined, isArray, isNumber } from "./is.js"; import { noop, noopValue as linear } from "./noop.js"; import { useRaf } from "../services/RafService.js"; let id = 0; const DEFAULT_PROGRESS_PRECISION = 1e-4; function normalizeEase(ease) { if (!isDefined(ease)) { return linear; } if (isArray(ease)) { return cubicBezier(...ease); } return ease; } function tween(callback, options = {}) { const raf = useRaf(); let progressValue = 0; let easedProgress = 0; const isSmooth = isDefined(options.smooth) && (isNumber(options.smooth) || options.smooth); const smoothFactor = isNumber(options.smooth) ? options.smooth : 0.1; const precision = options.precision ?? DEFAULT_PROGRESS_PRECISION; const ease = normalizeEase(options.easing); let delay = options.delay ?? 0; delay *= 1e3; let duration = options.duration ?? 1; duration *= 1e3; let startTime = getStartTime(); let endTime = getEndTime(startTime); const key = `tw-${id}`; id += 1; const { onStart = noop, onProgress = noop, onFinish = noop } = options; let isRunning = false; function pause() { isRunning = false; raf.remove(key); } function progress(newProgress) { if (!isDefined(newProgress)) { return easedProgress; } progressValue = newProgress; easedProgress = isSmooth ? damp(progressValue, easedProgress, smoothFactor, precision) : ease(progressValue); if (Math.abs(1 - easedProgress) < precision) { progressValue = 1; easedProgress = 1; } callback(easedProgress); onProgress(easedProgress); if (easedProgress === 1) { pause(); requestAnimationFrame(() => onFinish(easedProgress)); } return easedProgress; } function tick(props) { progress(clamp01(map(props.time, startTime, endTime, 0, 1))); } function getStartTime() { return performance.now() + delay; } function getEndTime(time) { return isSmooth ? inertiaFinalValue(time, 1) : time + duration; } function start() { onStart(0); startTime = getStartTime(); endTime = getEndTime(startTime); progressValue = 0; easedProgress = 0; isRunning = true; raf.add(key, tick); } function play() { if (isRunning) { return; } startTime = getStartTime() - lerp(0, duration, progressValue); endTime = getEndTime(startTime); isRunning = true; raf.add(key, tick); } return { start, finish: () => progress(1), pause, play, progress }; } export { normalizeEase, tween }; //# sourceMappingURL=tween.js.map