UNPKG

animbase

Version:
2 lines (1 loc) 10.9 kB
var AnimBase=function(){"use strict";const t=t=>t.match(/^([\w]{2})([\w]{2})([\w]{2})([\w]{2})$/).slice(1).map((t=>parseInt(t,16))),e=t=>{const e=t.match(/^#(?:([0-9a-fA-F]{3})|([0-9a-fA-F]{4})|([0-9a-fA-F]{6})|([0-9a-fA-F]{8}))$/);if(!e)throw Error("Unsupported color format");const[,n,a,o,r]=e;return n?n.split("").map((t=>t+t)).join("")+"ff":a?a.split("").map((t=>t+t)).join(""):o?o+"ff":r},n={linear:t=>t,ease:t=>t*t*(3-2*t),in:t=>t*t*t,out:t=>1-Math.pow(1-t,3),inOut:t=>t<.5?4*t*t*t:1-Math.pow(-2*t+2,3)/2,inQuad:t=>t*t,outQuad:t=>t*(2-t),inOutQuad:t=>t<.5?2*t*t:(4-2*t)*t-1,inCubic:t=>t*t*t,outCubic:t=>--t*t*t+1,inOutCubic:t=>t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1,inQuart:t=>t*t*t*t,outQuart:t=>1- --t*t*t*t,inOutQuart:t=>t<.5?8*t*t*t*t:1-8*--t*t*t*t,inQuint:t=>t*t*t*t*t,outQuint:t=>1+--t*t*t*t*t,inOutQuint:t=>t<.5?16*t*t*t*t*t:1+16*--t*t*t*t*t,inSine:t=>1-Math.cos(t*Math.PI/2),outSine:t=>Math.sin(t*Math.PI/2),inOutSine:t=>-(Math.cos(Math.PI*t)-1)/2,inExpo:t=>0===t?0:Math.pow(2,10*(t-1)),outExpo:t=>1===t?1:1-Math.pow(2,-10*t),inOutExpo:t=>0===t?0:1===t?1:t<.5?Math.pow(2,20*t-10)/2:(2-Math.pow(2,10-20*t))/2,inCirc:t=>1-Math.sqrt(1-Math.pow(t,2)),outCirc:t=>Math.sqrt(1-Math.pow(t-1,2)),inOutCirc:t=>t<.5?(1-Math.sqrt(1-Math.pow(2*t,2)))/2:(Math.sqrt(1-Math.pow(-2*t+2,2))+1)/2,inBack:t=>2.70158*t*t*t-1.70158*t*t,outBack:t=>1+2.70158*--t*t*t+1.70158*t*t,inOutBack:t=>t<.5?Math.pow(2*t,2)*(7.189819*t-2.5949095)/2:(Math.pow(2*t-2,2)*(3.5949095*(2*t-2)+2.5949095)+2)/2,inElastic:t=>0===t?0:1===t?1:-Math.pow(2,10*t-10)*Math.sin(2*(10*t-10.75)*Math.PI/3),outElastic:t=>0===t?0:1===t?1:Math.pow(2,-10*t)*Math.sin(2*(10*t-.75)*Math.PI/3)+1,inOutElastic:t=>0===t?0:1===t?1:t<.5?-Math.pow(2,20*t-10)*Math.sin(2*(20*t-11.125)*Math.PI/4.5)/2:Math.pow(2,-20*t+10)*Math.sin(2*(20*t-11.125)*Math.PI/4.5)/2+1,inBounce:t=>1-n.outBounce(1-t),outBounce:t=>t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375,inOutBounce:t=>t<.5?(1-n.outBounce(1-2*t))/2:(1+n.outBounce(2*t-1))/2,spring:(t,e=4.5,n=6)=>1-Math.cos(t*e*Math.PI)*Math.exp(-t*n)},a=(t,e,n,a,o)=>a+(t-e)*(o-a)/(n-e),o=new Set,r=(t,...e)=>{o.has(t)||(o.add(t),console.warn(...e))};let i={color:/#[0-9a-fA-F]{3,}/,number:/-?\d+(?:\.\d+)?/,unit:/[%a-zA-Z]*/,func:/[a-zA-Z]+/};i={...i,numberWithOptionalUnit:new RegExp(`(?:(${i.color.source})|(?:(${i.number.source})(${i.unit.source})?))`)},i={...i,numberWithOptionalUnitAndFunc:new RegExp(`${i.numberWithOptionalUnit.source}(?:\\.(${i.func.source}))?`)};const s=(t,e={})=>{const{strict:a=!1,warnOnce:o=r,context:s=""}=e,l=RegExp(i.numberWithOptionalUnitAndFunc.source,"g");let c;const u=[];for(;null!==(c=l.exec(t));){const[t,e,r,i,m]=c;if(m&&!n[m]){if(a)throw Error(`Invalid easing function: ${m}`);o(`animbase:ease:${m}:${s}`,"[AnimBase] Invalid easing function:",m,s)}u.push({type:e?"color":"number",text:t,value:e||parseFloat(r),unit:i,func:m&&n[m]?m:void 0,lastIndex:l.lastIndex})}return u};function l(t,e,n){const a=[...e].reverse(),o=[...n].reverse();for(let e=0;e<a.length;e++){const n=a[e].lastIndex-a[e].text.length,r=a[e].lastIndex;t=t.substring(0,n)+o[e]+t.substring(r)}return t}const c=({startValue:o,endValue:i,startFrame:s=0,endFrame:l,currentFrame:c,func:u="linear",type:m,strict:p=!1,warnOnce:f=r,context:h=""}={})=>{if(o===i)return o;const d=a(c,s,l,0,1),g=n[u](d);if("color"===m)try{return((n,a,o)=>{const r=t(e(a)),i=t(e(o));return"#"+r.map(((t,e)=>Math.round(Math.max(0,Math.min(255,t+(i[e]-t)*n))).toString(16).padStart(2,"0"))).join("")})(g,o,i)}catch(t){if(p)throw t;return f(`animbase:color:${h}`,"[AnimBase] Invalid color format:",o,i,h),g>=1?i:o}return a(g,0,1,o,i)},u={style:(t,e,n)=>{t.style[e]=n},setAttribute:(t,e,n)=>{t.setAttribute(e,n)},textContent:(t,e,n)=>{t.textContent=n},scrollProp:(t,e,n)=>{t[e]=parseFloat(n)},prop:(t,e,n)=>{t[e]=n},cssVar:(t,e,n)=>{t.style.setProperty(e,n)}},m={};class p{constructor(t,{init:e=null,config:n=null}={}){this.element=t,this.setConfig({init:e,config:n})}setConfig({init:t=null,config:e=null}={}){const n="true"===this.element.dataset.animStrict;this.strict=n;const a=this.element.dataset.animInit,o=this.element.dataset.animConfig;if(!t||!e){try{t=a?JSON.parse(a):{}}catch(t){if(n)throw t;r(`animbase:json:init:${this.element}`,"[AnimBase] Invalid data-anim-init JSON",a)}try{e=o?JSON.parse(o):{}}catch(t){if(n)throw t;r(`animbase:json:config:${this.element}`,"[AnimBase] Invalid data-anim-config JSON",o)}}t=t||{},e=e||{},this.rawInit=t,this.rawConfig=e;const i={};let l=0,c={};const u={};for(const[e,a]of Object.entries(t))u[e]=s(a,{strict:n,context:`prop:${e}`}),c[e]=[...u[e]];for(const[t,a]of Object.entries(e)){if("0"===t)continue;const e=parseInt(t);i[t]={startFrame:l,endFrame:e,ref:c,props:{}};for(const[e,o]of Object.entries(a)){const a=s(o,{strict:n,context:`prop:${e}`});c={...c,[e]:a},i[t].props[e]=a}l=e+1}this.initial=t,this.initialRef=u,this.styleConfig=i,this.styleEntries=Object.entries(i),this.lastFrame=null}update(t,e=!1){if(this.lastFrame===t)return e?{}:void 0;this.lastFrame=t;const n={},a=this.styleEntries;if(!a.length)return e?n:void 0;const o=a.find((([,e])=>t>=e.startFrame&&t<=e.endFrame)),r=o?.[1]??a.at(-1)[1],i=Boolean(o);for(const[a,o]of Object.entries(r.ref)){const p=i&&r.props[a]?r.props[a].map(((e,n)=>`${c({startValue:o[n].value,endValue:e.value,startFrame:r.startFrame,endFrame:r.endFrame,currentFrame:t,func:e.func,type:e.type,strict:this.strict,context:`prop:${a}`})}${e.unit||""}`)):r.props[a]?r.props[a].map((t=>`${t.value}${t.unit||""}`)):o.map((t=>`${t.value}${t.unit||""}`)),f=l(this.initial[a],this.initialRef[a],p);if(e)n[a]=f;else{const t=m[s=a]?m[s]:"d"===s||"value"===s||"viewBox"===s||"x"===s||"y"===s||"cx"===s||"cy"===s?"setAttribute":"text"===s?"textContent":"scrollTop"===s||"scrollLeft"===s?"scrollProp":"currentTime"===s||"volume"===s||"playbackRate"===s?"prop":s.startsWith("--")?"cssVar":"style",e="function"==typeof t?t:u[t];e&&e(this.element,a,f)}}var s;return e?n:void 0}}class f{constructor(t,e={}){this.getTimelineValue=t,this.animatedElements=new Map,this.timelineValue=NaN,this.elementSelector=e.elementSelector||"[data-anim-config]",this.autoCollect=e.autoCollect??!0,this.autoUpdate=e.autoUpdate??!0,this.autoCollect&&this.collectAnimatedElements(),this.autoUpdate&&this.updateTimeline()}collectAnimatedElements(){document.querySelectorAll(this.elementSelector).forEach((t=>this.addElement(t)))}addElement(t,e={}){const n=t instanceof p?t:new p(t,e);this.animatedElements.set(n.element,n)}removeElement(t){this.animatedElements.delete(t)}updateTimeline(){const t=this.getTimelineValue();t!==this.timelineValue&&(this.timelineValue=t,this.updateAllAnimatedElements())}updateAllAnimatedElements(){this.animatedElements.forEach((t=>t.update(this.timelineValue)))}}var h=Object.freeze({__proto__:null,AnimatedElement:p,TimelineAnimator:f,easingFunctions:n,linearInterpolation:a,parseExpression:s,registerHandlerType:function(t,e){u[t]=e},registerKeyHandler:function(t,e){if("function"==typeof e)return m[t]=e,void(u[t]=e);m[t]=e,"string"!=typeof e||u[e]||r(`animbase:handler:${e}`,"[AnimBase] Unknown handler type:",e,`for key "${t}"`)}});const d=new Map,g={};function w(t,e={}){let{configSelector:n,elementSelector:a,...o}=e;if(n){const t=document.querySelector(n);t?.dataset?.animTriggerConfig&&(o=JSON.parse(t.dataset.animTriggerConfig))}const r=o.max||100,i=1e3/(parseFloat(o.speed)||60)*r,s=o.autostart||!1;let l;return l=new f((()=>l?.state?.frame??(o.reverse?r:0)),a?{elementSelector:a}:{autoCollect:!1,autoUpdate:!1}),l.state={frame:0,max:r,duration:i,running:!1,startTime:0,pauseTime:0,once:o.once||!1,reverse:o.reverse||!1,onStart:o.onStart||null,onFinish:o.onFinish||null,from:null,to:null},d.set(t,l),s&&g.trigger(t),l}function M(t){const e=t.state,n=()=>{let a=(performance.now()-e.startTime)/e.duration;a=Math.max(0,Math.min(1,a));const o=(e.to??e.max)-(e.from??0);if(e.frame=Math.floor((e.from??0)+o*a),t.updateTimeline(),a>=1){if(e.once)return e.running=!1,void(e.onFinish&&e.onFinish());e.startTime=performance.now(),e.onFinish&&e.onFinish()}e.running&&requestAnimationFrame(n)};n()}["trigger","pause","resume","stop","seek","setOnce","setReverse","setHooks"].forEach((t=>{g[t]=function(e="default",n){const a=d.get(e);if(!a||!a.state)return;const o=a.state;switch(t){case"trigger":const t=n||{};if(!o.running){o.running=!0,"function"==typeof t.onStart&&(o.onStart=t.onStart),"function"==typeof t.onFinish&&(o.onFinish=t.onFinish),o.reverse=t.reverse??o.reverse,o.once=t.once??o.once,o.max=t.max??o.max,o.from="number"==typeof t.from?t.from:o.reverse?o.max:0,o.to="number"==typeof t.to?t.to:o.reverse?0:o.max,o.frame=o.from;const e=t.speed||(o.duration?1e3*Math.abs(o.to-o.from)/o.duration:60);o.duration=1e3/e*Math.abs(o.to-o.from),o.startTime=performance.now(),M(a)}break;case"pause":o.running=!1,o.pauseTime=performance.now();break;case"resume":const e=performance.now()-o.pauseTime;o.startTime+=e,o.running=!0,M(a);break;case"stop":o.running=!1,o.frame=o.reverse?o.max:0,a.updateTimeline();break;case"seek":o.frame=Math.max(0,Math.min(o.max,n||0)),a.updateTimeline();break;case"setOnce":o.once=!!n;break;case"setReverse":o.reverse=!!n;break;case"setHooks":const{onStart:r,onFinish:i}=n||{};r&&(o.onStart=r),i&&(o.onFinish=i)}}}));const b={scrollY:"scroll",scrollX:"scroll",scrollTop:"scroll",scrollLeft:"scroll",value:"input",currentTime:"timeupdate"},v="data-anim-controller-ref",x="data-anim-controlled-by",F="data-anim-trigger-group",$="data-anim-trigger-config";function A(){const t=document.querySelectorAll(`[${v}], [${x}], [${F}], [data-anim-init]`);t.forEach((t=>{let e=t.dataset.animControllerRef;const n=t.dataset.animControlledBy;["scrollTop","scrollY","scrollLeft","scrollX"].includes(n)?(e||(e="window"),t.setAttribute(v,e),"window"===e?("scrollLeft"===n&&t.setAttribute(x,"scrollX"),"scrollTop"===n&&t.setAttribute(x,"scrollY")):("scrollX"===n&&t.setAttribute(x,"scrollLeft"),"scrollY"===n&&t.setAttribute(x,"scrollTop"))):e&&"window"!==e&&!n?t.setAttribute(x,"value"):e||t.dataset.animTriggerGroup||t.setAttribute(F,"default")})),t.forEach((t=>{const e=t.dataset.animControllerRef,n=t.dataset.animControlledBy,a=t.dataset.animListen;if(e||n){const t=e&&"window"!==e?document.querySelector(e):window;if(!t)return console.warn("Missing controller:",e);const o=`${e||"window"}:${n||"value"}`;if(!d.has(o)){const r=new f((()=>parseFloat(t[n||"value"]||0)),{elementSelector:`[${v}="${e||""}"][${x}="${n}"]`});d.set(o,r);const i=a||b[n||"value"]||"input";t.addEventListener(i,(()=>r.updateTimeline()))}}else if(t.dataset.animTriggerGroup){const e=t.dataset.animTriggerGroup;d.has(e)||w(e,{configSelector:`[${F}="${e}"][${$}]`,elementSelector:`[${F}="${e}"]:not([${$}])`})}else;}))}g.play=g.trigger,g.setProgress=g.seek,g.refresh=A,g.getAnimator=t=>d.get(t),g.createTimedAnimator=w,document.addEventListener("DOMContentLoaded",A);return{...h,...g}}();