@ssgoi/core
Version:
Core animation engine for SSGOI - Native app-like page transitions with spring physics
2 lines (1 loc) • 8.88 kB
JavaScript
"use strict";var P=Object.defineProperty;var x=(e,t,n)=>t in e?P(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var y=(e,t,n)=>x(e,typeof t!="symbol"?t+"":t,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const O=require("popmotion"),M=require("./utils-BSgyev81.cjs");class A{constructor(t){y(this,"options");y(this,"currentValue");y(this,"velocity");y(this,"isAnimating",!1);y(this,"controls",null);y(this,"animationMap",null);y(this,"activeAnimations",new Set);y(this,"completedAnimations",new Set);y(this,"updatedProperties",new Set);y(this,"animate",(t=!1)=>{!this.isAnimating&&this.options.onStart&&this.options.onStart(),this.isAnimating=!0;const n=t?this.options.from:this.options.to;if(typeof this.currentValue=="object"&&this.currentValue!==null){this.animateObject(n,t);return}let i=this.currentValue,a=performance.now();const u={from:this.currentValue,to:n,stiffness:this.options.spring.stiffness,damping:this.options.spring.damping,mass:1};typeof this.velocity=="number"&&(u.velocity=this.velocity*1e3),this.controls=O.animate({...u,onUpdate:l=>{const m=performance.now(),p=(m-a)/1e3;if(p>0){if(typeof l=="number"&&typeof i=="number"){const f=(l-i)/p;this.velocity=f/1e3}else if(typeof l=="object"&&l!==null){const f={};Object.keys(l).forEach(d=>{const r=l[d],o=i[d];if(typeof r=="number"&&typeof o=="number"){const c=(r-o)/p;f[d]=c/1e3}}),this.velocity=f}i=l,a=m}this.currentValue=l,this.options.onUpdate(l)},onComplete:()=>{this.currentValue=n,this.isAnimating=!1,this.controls=null,typeof this.velocity=="object"&&this.velocity!==null?Object.keys(this.velocity).forEach(l=>{this.velocity[l]=0}):this.velocity=0,this.options.onComplete()}})});y(this,"animateObject",(t,n)=>{const i=this.currentValue,a=Object.keys(i);this.animationMap=new Map,this.activeAnimations.clear(),this.completedAnimations.clear(),this.updatedProperties.clear();const u={...i},l={};let m=!1;const p=()=>{const f=a.filter(r=>!this.completedAnimations.has(r));if(f.every(r=>this.updatedProperties.has(r))&&f.length>0){if(typeof this.velocity=="object"&&this.velocity){const r=performance.now();Object.keys(u).forEach(o=>{if(l[o]){const c=(r-l[o])/1e3,s=this.currentValue[o],h=u[o];typeof s=="number"&&typeof h=="number"&&c>0&&(this.velocity[o]=(h-s)/c/1e3)}l[o]=r})}this.currentValue={...u},this.options.onUpdate(this.currentValue),this.updatedProperties.clear(),!m&&this.options.onStart&&(m=!0,this.options.onStart())}};a.forEach(f=>{this.activeAnimations.add(f);const d={from:i[f],to:t[f],stiffness:this.options.spring.stiffness,damping:this.options.spring.damping,mass:1};typeof this.velocity=="object"&&this.velocity&&f in this.velocity&&(d.velocity=this.velocity[f]*1e3);const r=O.animate({...d,onUpdate:o=>{u[f]=o,this.updatedProperties.add(f),p()},onComplete:()=>{this.completedAnimations.add(f),this.updatedProperties.delete(f),this.completedAnimations.size===a.length&&(this.currentValue=t,this.isAnimating=!1,this.animationMap=null,typeof this.velocity=="object"&&this.velocity&&Object.keys(this.velocity).forEach(o=>{this.velocity[o]=0}),this.options.onComplete())}});this.animationMap.set(f,r)})});if(this.options={from:t.from??0,to:t.to??1,spring:t.spring??{stiffness:100,damping:10},onUpdate:t.onUpdate??(()=>{}),onComplete:t.onComplete??(()=>{}),onStart:t.onStart},this.currentValue=this.options.from,typeof this.options.from=="object"&&this.options.from!==null){const n={};Object.keys(this.options.from).forEach(i=>{n[i]=0}),this.velocity=n}else this.velocity=0}forward(){this.stop(),this.animate(!1)}backward(){this.stop(),this.animate(!0)}reverse(){const t=this.options.from;if(this.options.from=this.options.to,this.options.to=t,this.isAnimating){const n=this.shouldReverse();this.stop(),this.animate(!n)}}shouldReverse(){return typeof this.currentValue=="number"&&typeof this.options.from=="number"&&typeof this.options.to=="number"?this.currentValue>(this.options.from+this.options.to)/2:!1}stop(){this.isAnimating=!1,this.controls&&(this.controls.stop(),this.controls=null),this.animationMap&&(this.animationMap.forEach(t=>{t.stop()}),this.animationMap.clear(),this.animationMap=null),this.updatedProperties.clear()}getVelocity(){return this.velocity}getCurrentValue(){return this.currentValue}getIsAnimating(){return this.isAnimating}getCurrentState(){return{position:this.currentValue,velocity:this.velocity,from:this.options.from,to:this.options.to}}setVelocity(t){this.velocity=t}setValue(t){this.currentValue=t}updateOptions(t){if(this.options={...this.options,...t},this.isAnimating&&this.controls){const n=this.shouldReverse();this.stop(),this.animate(!n)}}static fromState(t,n){const i=new A(n);return i.setValue(t.position),i.setVelocity(t.velocity),i}}const R=Symbol.for("TRANSITION_STRATEGY"),j=e=>({runIn:async t=>{const{currentAnimation:n}=e;if(n&&n.direction==="out"){const l=n.animator.getCurrentState();if(n.animator.stop(),t.out){const m=await t.out,{from:p=1,to:f=0}=m;return{config:m,state:l,from:p,to:f,direction:"backward"}}}const i=await t.in;if(!i)return{state:{position:0,velocity:0},from:0,to:1,direction:"forward"};const{from:a=0,to:u=1}=i;return{config:i,state:{position:a,velocity:0},from:a,to:u,direction:"forward"}},runOut:async t=>{const{currentAnimation:n}=e;if(n&&n.direction==="in"){const l=n.animator.getCurrentState();if(n.animator.stop(),t.in){const m=await t.in,{from:p=0,to:f=1}=m;return{config:m,state:{position:l.position,velocity:l.velocity},from:p,to:f,direction:"backward"}}}const i=await t.out;if(!i)return{state:{position:1,velocity:0},from:1,to:0,direction:"forward"};const{from:a=1,to:u=0}=i;return{config:i,state:{position:a,velocity:0},from:a,to:u,direction:"forward"}}});function U(e,t){var d;let n=null,i=null,a=null,u=null;const l={get currentAnimation(){return n}},m=((d=t==null?void 0:t.strategy)==null?void 0:d.call(t,l))||j(l),p=async r=>{var g,b;i&&(i.remove(),i=null);const o=e(),c={in:o.in&&Promise.resolve(o.in(r)),out:o.out&&Promise.resolve(o.out(r))},s=await m.runIn(c);if(!s.config)return;(b=(g=s.config).prepare)==null||b.call(g,r);const h=A.fromState(s.state,{from:s.from,to:s.to,spring:s.config.spring,onStart:s.config.onStart,onUpdate:s.config.tick,onComplete:()=>{var v,S;n=null,(S=(v=s.config)==null?void 0:v.onEnd)==null||S.call(v)}});n={animator:h,direction:"in"},s.direction==="forward"?h.forward():h.backward()},f=async r=>{var b,v;i=r;const o=e(),c={in:o.in&&Promise.resolve(o.in(r)),out:o.out&&Promise.resolve(o.out(r))},s=await m.runOut(c);if(!s.config)return;(v=(b=s.config).prepare)==null||v.call(b,r),g();const h=A.fromState(s.state,{from:s.from,to:s.to,spring:s.config.spring,onStart:s.config.onStart,onUpdate:s.config.tick,onComplete:()=>{var S,T,E;(T=(S=s.config)==null?void 0:S.onEnd)==null||T.call(S),i&&(i.remove(),i=null),n=null,(E=t==null?void 0:t.onCleanupEnd)==null||E.call(t)}});n={animator:h,direction:"out"},s.direction==="forward"?h.forward():h.backward();function g(){!a||!i||(u&&a.contains(u)?a.insertBefore(i,u):a.appendChild(i))}};return r=>{if(r)return a=r.parentElement,u=r.nextElementSibling,p(r),()=>{const o=r.cloneNode(!0);f(o)}}}const V=new Map,C=new Map;function I(e,t,n){V.set(e,t);let i=C.get(e);return i||(i=U(()=>{const a=V.get(e);return a||(console.warn(`Transition "${String(e)}" not found`),{})},{strategy:n,onCleanupEnd:()=>D(e)}),C.set(e,i),i)}function D(e){V.delete(e),C.delete(e)}function N(e){return I(e.key,{in:e.in,out:e.out},e[R])}function G(e){let t=null;const n=[...e.transitions],i=[];for(const o of e.transitions)o.symmetric&&(n.some(s=>s.from===o.to&&s.to===o.from)||i.push({from:o.to,to:o.from,transition:o.transition}));n.push(...i);let a=null;const u=new Map;let l=null;const m=()=>{a&&l&&u.set(l,{x:a.scrollLeft,y:a.scrollTop})},p=(o,c)=>{a||(a=M.getScrollingElement(o),a.addEventListener("scroll",m,{passive:!0})),l=c},f=()=>{const o=t==null?void 0:t.from,c=t==null?void 0:t.to,s=o&&u.has(o)?u.get(o):{x:0,y:0},h=c&&u.has(c)?u.get(c):{x:0,y:0};return{x:-h.x+s.x,y:-h.y+s.y}};function d(){if(t!=null&&t.from&&(t!=null&&t.to)){const c=L(t.from,t.to,n)||e.defaultTransition,h={scrollOffset:f()};c&&(c.out&&t.outResolve&&t.outResolve(g=>c.out(g,h)),c.in&&t.inResolve&&t.inResolve(g=>c.in(g,h))),t=null}}const r=async(o,c)=>c==="in"&&(!t||!t.from)?()=>({}):(t||(t={}),c==="out"?(t.from=o,new Promise(s=>{t.outResolve=s,d()})):(t.to=o,new Promise(s=>{t.inResolve=s,d()})));return o=>({key:o,in:async c=>(p(c,o),(await r(o,"in"))(c)),out:async c=>(await r(o,"out"))(c)})}function L(e,t,n){for(const i of n)if(w(e,i.from)&&w(t,i.to))return i.transition;for(const i of n)if((i.from==="*"||w(e,i.from))&&(i.to==="*"||w(t,i.to)))return i.transition;return null}function w(e,t){if(t==="*")return!0;if(t.endsWith("/*")){const n=t.slice(0,-2);return e===n||e.startsWith(n+"/")}return e===t}exports.TRANSITION_STRATEGY=R;exports.createDefaultStrategy=j;exports.createSggoiTransitionContext=G;exports.transition=N;