UNPKG

threepipe

Version:

A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.

136 lines 3.88 kB
import { animate, anticipate, backIn, backInOut, backOut, bounceIn, bounceInOut, bounceOut, circIn, circInOut, circOut, easeIn, easeInOut, easeOut, linear, } from 'popmotion'; import { timeout } from 'ts-browser-helpers'; import { MathUtils } from 'three'; export { animate }; function easeInOutSine(x) { return -(Math.cos(Math.PI * x) - 1) / 2; } // eslint-disable-next-line @typescript-eslint/naming-convention export const EasingFunctions = { linear: linear, easeIn: easeIn, easeOut: easeOut, easeInOut: easeInOut, circIn: circIn, circOut: circOut, circInOut: circInOut, backIn: backIn, backOut: backOut, backInOut: backInOut, anticipate: anticipate, bounceOut: bounceOut, bounceIn: bounceIn, bounceInOut: bounceInOut, easeInOutSine: easeInOutSine, }; export function makeSetterFor(target, key, setDirty) { const v = target[key]; const dirty = () => { // if (typeof target?.setDirty === 'function') target.setDirty() setDirty?.(); }; const isBool = typeof v === 'boolean'; if (v && v.isColor) return (a) => { v.set(a); dirty(); }; else if (v && typeof v.copy === 'function') return (a) => { v.copy(a); dirty(); }; else return (a) => { target[key] = !isBool ? a : !!a; dirty(); }; } export async function animateTarget(target, key, options, animations, forceCurrent = false) { if (!(key in target)) { console.error('invalid key', key, target); } const setter = makeSetterFor(target, key); const fromVal = forceCurrent || options.from === undefined ? target[key] : options.from; const onUpdate = (val) => { setter(val); options.onUpdate && options.onUpdate(val); }; if (typeof fromVal === 'boolean') { const { duration } = options; // todo: divide by 2? or support keyframes. return timeout(duration ?? 0).then(() => onUpdate(options.to)); } else { if (typeof options.to === 'function') { options = { ...options, to: options.to(fromVal, target) }; // need to duplicate options } return animateAsync({ ...options, from: fromVal, onUpdate, }, animations); } } export async function animateAsync(options, animations) { const complete = options.onComplete; const stop = options.onStop; const end = options.onEnd; options = { ...options }; return new Promise((resolve, reject) => { const end2 = () => { try { end?.(); } catch (e) { reject(e); return false; } return true; }; options.onComplete = () => { try { complete?.(); } catch (e) { if (!end2()) return; reject(e); return; } if (!end2()) return; resolve(); }; options.onStop = () => { try { stop?.(); } catch (e) { if (!end2()) return; reject(e); return; } if (!end2()) return; resolve(); }; const an = animate(options); if (animations) animations.push(an); }); } export function lerpAngle(a, b, t) { const d = b - a; if (d >= Math.PI) { return a + (d - Math.PI * 2) * t; } else if (d <= -Math.PI) { return a + (d + Math.PI * 2) * t; } else { return a + d * t; } } export const lerp = MathUtils.lerp; //# sourceMappingURL=animation.js.map