svg-scroll-draw 2.2.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/angular/index.cjs +3 -3
- package/dist/angular/index.d.mts +194 -9
- package/dist/angular/index.d.ts +194 -9
- package/dist/angular/index.mjs +3 -3
- package/dist/astro/index.cjs +3 -3
- package/dist/astro/index.d.mts +78 -1
- package/dist/astro/index.d.ts +78 -1
- package/dist/astro/index.mjs +3 -3
- package/dist/cdn/svg-scroll-draw.global.js +3 -3
- package/dist/devtools/index.cjs +1 -1
- package/dist/devtools/index.d.mts +12 -0
- package/dist/devtools/index.d.ts +12 -0
- package/dist/devtools/index.mjs +1 -1
- package/dist/group/index.cjs +3 -3
- package/dist/group/index.d.mts +88 -1
- package/dist/group/index.d.ts +88 -1
- package/dist/group/index.mjs +3 -3
- package/dist/index.cjs +4 -4
- package/dist/index.d.mts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.mjs +4 -4
- package/dist/lenis/index.cjs +1 -0
- package/dist/lenis/index.d.mts +51 -0
- package/dist/lenis/index.d.ts +51 -0
- package/dist/lenis/index.mjs +1 -0
- package/dist/nuxt/index.cjs +3 -3
- package/dist/nuxt/index.d.mts +286 -5
- package/dist/nuxt/index.d.ts +286 -5
- package/dist/nuxt/index.mjs +3 -3
- package/dist/pin/index.cjs +1 -0
- package/dist/pin/index.d.mts +29 -0
- package/dist/pin/index.d.ts +29 -0
- package/dist/pin/index.mjs +1 -0
- package/dist/react/index.cjs +3 -3
- package/dist/react/index.d.mts +16 -0
- package/dist/react/index.d.ts +16 -0
- package/dist/react/index.mjs +3 -3
- package/dist/snap/index.cjs +1 -0
- package/dist/snap/index.d.mts +30 -0
- package/dist/snap/index.d.ts +30 -0
- package/dist/snap/index.mjs +1 -0
- package/dist/solid/index.cjs +3 -3
- package/dist/solid/index.d.mts +171 -1
- package/dist/solid/index.d.ts +171 -1
- package/dist/solid/index.mjs +3 -3
- package/dist/svelte/index.cjs +3 -3
- package/dist/svelte/index.d.mts +183 -10
- package/dist/svelte/index.d.ts +183 -10
- package/dist/svelte/index.mjs +3 -3
- package/dist/vue/index.cjs +3 -3
- package/dist/vue/index.d.mts +278 -1
- package/dist/vue/index.d.ts +278 -1
- package/dist/vue/index.mjs +3 -3
- package/dist/web-component/index.cjs +3 -3
- package/dist/web-component/index.mjs +3 -3
- package/package.json +16 -1
package/README.md
CHANGED
|
@@ -429,15 +429,15 @@ devtools.highlight('#my-element'); // outline for 2 seconds
|
|
|
429
429
|
|---|---|
|
|
430
430
|
| `svg-scroll-draw` | `scrollDraw`, `scrollAnimate`, `scrollCounter`, `scrollParallax`, `PRESETS`, easing factories |
|
|
431
431
|
| `svg-scroll-draw/react` | `ScrollDraw`, `ScrollAnimate`, `ScrollCounter`, `ScrollVideo`, `ScrollText`, `useScrollDrawProgress` |
|
|
432
|
-
| `svg-scroll-draw/vue` | `ScrollDraw`, `useScrollDraw` |
|
|
433
|
-
| `svg-scroll-draw/svelte` | `scrollDraw` action, `createScrollDraw` |
|
|
434
|
-
| `svg-scroll-draw/solid` | `useScrollDraw`, `createScrollDraw` |
|
|
435
|
-
| `svg-scroll-draw/angular` | `ScrollDrawRef` |
|
|
436
|
-
| `svg-scroll-draw/astro` | `initScrollDraw()` |
|
|
437
|
-
| `svg-scroll-draw/nuxt` | `
|
|
432
|
+
| `svg-scroll-draw/vue` | `ScrollDraw`, `useScrollDraw` · **v2:** `ScrollAnimate`, `ScrollCounter`, `ScrollVideo`, `ScrollText`, `useScrollAnimate`, `useScrollCounter`, `useScrollVideo`, `useScrollText` |
|
|
433
|
+
| `svg-scroll-draw/svelte` | `scrollDraw` action, `createScrollDraw` · **v2:** `scrollAnimate`, `scrollCounterAction`, `scrollVideoAction`, `scrollTextAction`, `createScrollAnimate`, `createScrollCounter`, `createScrollVideo`, `createScrollText` |
|
|
434
|
+
| `svg-scroll-draw/solid` | `useScrollDraw`, `createScrollDraw` · **v2:** `useScrollAnimate`, `useScrollCounter`, `useScrollVideo`, `useScrollText`, `createScrollAnimate`, `createScrollCounter`, `createScrollVideo`, `createScrollText` |
|
|
435
|
+
| `svg-scroll-draw/angular` | `ScrollDrawRef` · **v2:** `ScrollAnimateRef`, `ScrollCounterRef`, `ScrollVideoRef`, `ScrollTextRef` |
|
|
436
|
+
| `svg-scroll-draw/astro` | `initScrollDraw()` · **v2:** `initScrollAnimate()`, `initScrollCounter()`, `initScrollText()`, `initAll()` |
|
|
437
|
+
| `svg-scroll-draw/nuxt` | All Vue v1+v2 composables and components, `createScrollDrawPlugin()` |
|
|
438
438
|
| `svg-scroll-draw/video` | `scrollVideo` |
|
|
439
439
|
| `svg-scroll-draw/text` | `scrollText` |
|
|
440
|
-
| `svg-scroll-draw/group` | `scrollDrawGroup`, `scrollDrawSequence` |
|
|
440
|
+
| `svg-scroll-draw/group` | `scrollDrawGroup`, `scrollDrawSequence` · **v2:** `scrollAnimateGroup`, `scrollAnimateSequence`, `scrollParallaxGroup` |
|
|
441
441
|
| `svg-scroll-draw/timeline` | `scrollDrawTimeline` |
|
|
442
442
|
| `svg-scroll-draw/cinematic` | `Cinematic` |
|
|
443
443
|
| `svg-scroll-draw/devtools` | `devtools` (dev-only) |
|
package/dist/angular/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';function
|
|
2
|
-
<div style="position:absolute;${
|
|
3
|
-
<div style="position:absolute;${S?`left:${x}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${x}px;left:0;right:0;border-top:2px dashed #ef4444;`}padding:2px 6px;color:#ef4444;background:rgba(0,0,0,.6)">\u25A0 end</div>`;}return document.body.appendChild(o),window.addEventListener("scroll",h,{passive:true}),h(),o}function Ie(e,n,s){let o=(n.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),h=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,g=>{let D=parseFloat(g),x=o[h++]??D;return String(+(D+(x-D)*s).toFixed(4))})}function Xe(e,n={}){if(typeof window>"u")return {destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};let{preset:s,...o}=n,h=s?{...Ge[s],...o}:o,g=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:D="path, polyline, line, polygon, rect, circle",speed:x=1,fade:S=false,easing:p="linear",trigger:E={},stagger:G=0,direction:d="forward",once:K=false,debug:je=false,axis:N="y",scrollContainer:$e,autoReverse:me=false,delay:ue=0,strokeColor:Q,strokeWidth:Y,fillOpacity:Z,waypoints:ee,velocityScale:pe=false,threshold:Oe=0,rootMargin:Fe="0px",repeat:te=0,repeatDelay:Me=0,morphTo:H,clip:Se,autoplay:Je=false,duration:Ke=1e3,native:Qe=true,onProgress:ce,onStart:de,onComplete:ae}=h,_=Se===true?"left":typeof Se=="string"?Se:false,re=typeof p=="function"?p:Pe[p]??Pe.linear,Ce=Le(E.start??"top bottom"),Re=Le(E.end??"bottom top"),I=typeof $e=="string"?document.querySelector($e):$e??null,W=Array.isArray(Q)?Q[0]:null,T=Array.isArray(Q)?Q[1]:typeof Q=="string"?Q:null,O=Array.isArray(Y)?Y[0]:null,k=Array.isArray(Y)?Y[1]:typeof Y=="number"?Y:null,F=Array.isArray(Z)?Z[0]:null,A=Array.isArray(Z)?Z[1]:typeof Z=="number"?Z:null;function ne(t){let r=t*100;switch(_){case "right":return `inset(0 0 0 ${100-r}%)`;case "top":return `inset(0 0 ${100-r}% 0)`;case "bottom":return `inset(${100-r}% 0 0 0)`;case "center":return `circle(${t*150}% at 50% 50%)`;default:return `inset(0 ${100-r}% 0 0)`}}let $=_?[]:Array.from(e.querySelectorAll(D)),w=[],z=[],X=0,U=0,M=false,R=false,v=0,ye=false,q=-1,he=-1,P=false,se=0,B=0,j,Te=null,J=new Set,ge=-1,Ne=performance.now();function fe(){return I?N==="x"?I.scrollLeft:I.scrollTop:N==="x"?window.scrollX:window.scrollY}function He(){return I?N==="x"?I.clientWidth:I.clientHeight:N==="x"?window.innerWidth:window.innerHeight}function We(){let t=e.getBoundingClientRect(),r,l,y;if(I){let L=I.getBoundingClientRect();r=N==="x"?t.left-L.left+I.scrollLeft:t.top-L.top+I.scrollTop,l=N==="x"?t.width:t.height,y=fe();}else r=N==="x"?t.left:t.top,l=N==="x"?t.width:t.height,y=fe();let C=De({top:r,height:l},y,He(),Ce,Re);X=C.tStart,U=C.tEnd,je&&process.env.NODE_ENV!=="production"&&(Te?.remove(),Te=lt(X,U,N));}function Ye(t,r){if(e.style.setProperty("--scroll-draw-progress",String(t)),_){let l=r==="reverse"?1-t:t;e.style.clipPath=ne(l);return}$.forEach((l,y)=>{l.style.strokeDashoffset=r==="reverse"?`${w[y]*t}`:`${w[y]*(1-t)}`,S&&(l.style.opacity=r==="reverse"?`${1-t}`:`${t}`),W&&T?l.style.stroke=xe(W,T,t):T&&(l.style.stroke=T),O!==null&&k!==null?l.style.strokeWidth=`${O+(k-O)*t}`:k!==null&&(l.style.strokeWidth=`${k}`),F!==null&&A!==null?l.style.fillOpacity=`${F+(A-F)*t}`:A!==null&&(l.style.fillOpacity=`${A}`),H&&l.tagName.toLowerCase()==="path"&&z[y]&&l.setAttribute("d",Ie(z[y],H,t));});}function be(){if(e.style.setProperty("--scroll-draw-progress","0"),_){e.style.clipPath=ne(0);return}$.forEach((t,r)=>{t.style.strokeDasharray=`${w[r]}`,t.style.strokeDashoffset=d==="reverse"?"0":`${w[r]}`,S?t.style.opacity=d==="reverse"?"1":"0":t.style.opacity="",W&&(t.style.stroke=W),O!==null&&(t.style.strokeWidth=`${O}`),F!==null&&(t.style.fillOpacity=`${F}`),H&&t.tagName.toLowerCase()==="path"&&z[r]&&t.setAttribute("d",z[r]);});}if($.forEach(t=>{at(t);let r=Ee(t);w.push(r),t.tagName.toLowerCase()==="path"?z.push(t.getAttribute("d")??""):z.push(""),g?(t.style.strokeDasharray=`${r}`,t.style.strokeDashoffset=d==="reverse"?`${r}`:"0",S&&(t.style.opacity="1"),T&&(t.style.stroke=T),k!==null&&(t.style.strokeWidth=`${k}`),A!==null&&(t.style.fillOpacity=`${A}`),H&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",H)):(t.style.strokeDasharray=`${r}`,t.style.strokeDashoffset=d==="reverse"?"0":`${r}`,S?t.style.opacity=d==="reverse"?"1":"0":t.style.opacity="",W&&(t.style.stroke=W),O!==null&&(t.style.strokeWidth=`${O}`),F!==null&&(t.style.fillOpacity=`${F}`));}),_){if(g)return e.style.clipPath=ne(1),ae?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};e.style.clipPath=ne(0);}else if(g)return ae?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};function Ze(){return !(Qe===false||!it()||!$.length||typeof p!="string"||!(p in _e)||_||N!=="y"||I||x!==1||G!==0||K||me||pe!==false||H||ee||te||ue>0||ce||de||ae||Q!=null||Y!=null||Z!=null||(E.start??"top bottom").trim()!=="top bottom"||(E.end??"bottom top").trim()!=="bottom top")}function et(){let t=`svg-scroll-draw-${++ot}`,r=d==="reverse"?"0":"var(--ssd-len)",l=d==="reverse"?"var(--ssd-len)":"0",y=`stroke-dashoffset:${r};`,C=`stroke-dashoffset:${l};`;S&&(y+=`opacity:${d==="reverse"?1:0};`,C+=`opacity:${d==="reverse"?0:1};`);let L=document.createElement("style");L.setAttribute("data-svg-scroll-draw",""),L.textContent=`@keyframes ${t}{from{${y}}to{${C}}}.${t}{animation-name:${t};animation-duration:auto;animation-timing-function:${_e[p]};animation-fill-mode:both;animation-timeline:view();animation-range:cover 0% cover 100%;}`,document.head.appendChild(L);function a(i,c){i.style.setProperty("--ssd-len",String(w[c])),i.style.strokeDasharray=`${w[c]}`,i.style.strokeDashoffset="",i.style.opacity="",i.style.animationPlayState="",i.classList.add(t);}$.forEach(a);let f=false,b=-1;function u(){if(b>=0)return b;let i=e.getBoundingClientRect(),{tStart:c,tEnd:m}=De({top:i.top,height:i.height},fe(),He(),Ce,Re);return re(ie(fe(),c,m,x))}return {destroy(){$.forEach(i=>{i.classList.remove(t),i.style.removeProperty("--ssd-len"),i.style.animationPlayState="";}),L.remove();},replay(){f=false,b=-1,$.forEach(a);},pause(){f=true,$.forEach(i=>{i.style.animationPlayState="paused";});},resume(){f&&(f=false,$.forEach(i=>{i.style.animationPlayState="running";}));},seek(i){let c=Math.min(1,Math.max(0,i));b=c,f=true,$.forEach((m,oe)=>{m.classList.remove(t),m.style.strokeDashoffset=d==="reverse"?`${w[oe]*c}`:`${w[oe]*(1-c)}`,S&&(m.style.opacity=d==="reverse"?`${1-c}`:`${c}`);});},getProgress(){return u()}}}if(Ze())return et();function tt(){let t=Math.max(1,Ke),r=0,l=0;function y(u){let i=true;if(_){let c=Math.min(1,Math.max(0,u/t)),m=re(c);se=m,e.style.setProperty("--scroll-draw-progress",String(m)),e.style.clipPath=ne(d==="reverse"?1-m:m),ce?.(m),c<1&&(i=false);}else $.forEach((c,m)=>{let oe=m*G*t,le=Math.min(1,Math.max(0,(u-oe)/t)),V=re(le);c.style.strokeDashoffset=d==="reverse"?`${w[m]*V}`:`${w[m]*(1-V)}`,S&&(c.style.opacity=d==="reverse"?`${1-V}`:`${V}`),W&&T?c.style.stroke=xe(W,T,V):T&&(c.style.stroke=T),O!==null&&k!==null?c.style.strokeWidth=`${O+(k-O)*V}`:k!==null&&(c.style.strokeWidth=`${k}`),F!==null&&A!==null?c.style.fillOpacity=`${F+(A-F)*V}`:A!==null&&(c.style.fillOpacity=`${A}`),H&&c.tagName.toLowerCase()==="path"&&z[m]&&c.setAttribute("d",Ie(z[m],H,V)),m===0&&(ce?.(V),e.style.setProperty("--scroll-draw-progress",String(V))),le<1&&(i=false);});if(ee){let c=Math.min(1,Math.max(0,u/t)),m=re(c);for(let oe in ee){let le=parseFloat(oe);m>=le&&!J.has(le)&&(J.add(le),ee[oe]?.());}}return i}function C(u){if(P)return;let i=u-r;R||(R=true,de?.());let c=y(i);if(c&&!M){M=true,y(t*(1+Math.max(0,$.length-1)*G)),ae?.(),B<(te==="infinite"?1/0:te??0)&&(B++,j=setTimeout(()=>{r=performance.now(),R=false,M=false,J.clear(),be(),v=requestAnimationFrame(C);},Me));return}c||(v=requestAnimationFrame(C));}function L(){cancelAnimationFrame(v),clearTimeout(j),r=performance.now(),l=0,P=false,R=false,M=false,B=0,J.clear(),be(),v=requestAnimationFrame(C);}let a=new IntersectionObserver(u=>{u.forEach(i=>{i.isIntersecting&&!(K&&M)?L():!i.isIntersecting&&!K&&!M&&(cancelAnimationFrame(v),clearTimeout(j),r=null);});},{root:I??null,threshold:Oe,rootMargin:Fe}),f;function b(){clearTimeout(f),f=setTimeout(()=>{$.forEach((u,i)=>{w[i]=Ee(u),u.style.strokeDasharray=`${w[i]}`;});},150);}return window.addEventListener("resize",b),window.addEventListener("orientationchange",b),ue>0?setTimeout(()=>a.observe(e),ue):a.observe(e),{destroy(){cancelAnimationFrame(v),clearTimeout(j),a.disconnect(),window.removeEventListener("resize",b),window.removeEventListener("orientationchange",b),clearTimeout(f);},replay(){B=0,L();},pause(){P||(P=true,l=performance.now()-r,cancelAnimationFrame(v));},resume(){P&&(P=false,r=performance.now()-l,v=requestAnimationFrame(C));},seek(u){let i=Math.min(1,Math.max(0,u));se=i,P=true,l=i*t,r=performance.now()-l,cancelAnimationFrame(v),y(l);},getProgress(){return se}}}if(Je)return tt();We();function we(){if(!ye||P)return;let t=performance.now(),r=fe(),l=x;if(pe!==false){let a=t-Ne,f=a>0?Math.abs(r-(ge<0?r:ge))/a:0;l=x*Math.max(.2,1+f*(typeof pe=="number"?pe:1)*.04);}ge=r,Ne=t;let y=me?he===-1||r>=he?"forward":"reverse":d;he=r;let C=U-X,L=true;if(_){let a=re(ie(r,X,U,l));K&&!me&&(q=Math.max(q,a),a=q),se=a,e.style.setProperty("--scroll-draw-progress",String(a));let f=y==="reverse"?1-a:a;e.style.clipPath=ne(f),ce?.(a),!R&&ie(r,X,U,l)>0&&(R=true,de?.()),a>=1&&!M?(M=true,ae?.(),B<(te==="infinite"?1/0:te??0)&&(B++,j=setTimeout(()=>{q=-1,R=false,M=false,e.style.clipPath=ne(0);},Me))):a<1&&!K&&(M=false),v=requestAnimationFrame(we);return}if($.forEach((a,f)=>{let b=f*G*C,u=re(ie(r,X+b,U+b,l));K&&!me&&(q=Math.max(q,u),u=q),se=u,a.style.strokeDashoffset=y==="reverse"?`${w[f]*u}`:`${w[f]*(1-u)}`,S&&(a.style.opacity=y==="reverse"?`${1-u}`:`${u}`),W&&T?a.style.stroke=xe(W,T,u):T&&(a.style.stroke=T),O!==null&&k!==null?a.style.strokeWidth=`${O+(k-O)*u}`:k!==null&&(a.style.strokeWidth=`${k}`),F!==null&&A!==null?a.style.fillOpacity=`${F+(A-F)*u}`:A!==null&&(a.style.fillOpacity=`${A}`),H&&a.tagName.toLowerCase()==="path"&&z[f]&&a.setAttribute("d",Ie(z[f],H,u)),f===0&&(ce?.(u),e.style.setProperty("--scroll-draw-progress",String(u))),u<1&&(L=false);}),ee){let a=re(ie(r,X,U,l));for(let f in ee){let b=parseFloat(f);a>=b&&!J.has(b)&&(J.add(b),ee[f]?.());}}!R&&ie(r,X,U,l)>0&&(R=true,de?.()),L&&!M?(M=true,ae?.(),B<(te==="infinite"?1/0:te??0)&&(B++,j=setTimeout(()=>{q=-1,R=false,M=false,J.clear(),be();},Me))):!L&&!K&&(M=false),v=requestAnimationFrame(we);}let ke=new IntersectionObserver(t=>{t.forEach(r=>{ye=r.isIntersecting,ye&&!P?v=requestAnimationFrame(we):cancelAnimationFrame(v);});},{root:I??null,threshold:Oe,rootMargin:Fe}),Ae;function ve(){clearTimeout(Ae),Ae=setTimeout(()=>{$.forEach((t,r)=>{w[r]=Ee(t),t.style.strokeDasharray=`${w[r]}`;}),We();},150);}return window.addEventListener("resize",ve),window.addEventListener("orientationchange",ve),ue>0?setTimeout(()=>ke.observe(e),ue):ke.observe(e),{destroy(){cancelAnimationFrame(v),clearTimeout(j),ke.disconnect(),window.removeEventListener("resize",ve),window.removeEventListener("orientationchange",ve),clearTimeout(Ae),Te?.remove();},replay(){q=-1,he=-1,ge=-1,R=false,M=false,B=0,P=false,J.clear(),clearTimeout(j),be();},pause(){P=true,cancelAnimationFrame(v);},resume(){P&&(P=false,ye&&(v=requestAnimationFrame(we)));},seek(t){let r=Math.min(1,Math.max(0,t));se=r,q=r,P=true,cancelAnimationFrame(v),Ye(r,d);},getProgress(){return se}}}var Ue=class{constructor(){this.instance=null;}init(n,s={}){return this.destroy(),this.instance=Xe(n,s),this}replay(){return this.instance?.replay(),this}destroy(){return this.instance?.destroy(),this.instance=null,this}};exports.ScrollDrawRef=Ue;
|
|
1
|
+
'use strict';function Mt({bounces:e=3,decay:r=.5}={}){let n=Math.max(1,Math.round(e)),t=Math.max(.01,Math.min(.99,r)),u=Math.sqrt(t),o=0,f=[];for(let y=0;y<n;y++){let $=Math.pow(u,y);f.push($),o+=$;}let l=[0],c=0;for(let y=0;y<n;y++)c+=f[y]/o,l.push(c);return y=>{if(y<=0)return 0;if(y>=1)return 1;for(let $=0;$<n;$++)if(y<=l[$+1]){let B=(y-l[$])/(l[$+1]-l[$]);if($===0)return B*(2-B);let S=1-Math.pow(t,$);return S+(1-S)*(2*B-1)*(2*B-1)}return 1}}function Pt({amplitude:e=1,period:r=.4}={}){let n=Math.max(1,e),t=Math.max(.1,r),u=n<=1?t/4:t/(2*Math.PI)*Math.asin(1/n);return o=>o<=0?0:o>=1?1:n*Math.pow(2,-10*o)*Math.sin((o-u)*(2*Math.PI)/t)+1}var ie={linear:e=>e,"ease-in":e=>e*e,"ease-out":e=>e*(2-e),"ease-in-out":e=>e<.5?2*e*e:-1+(4-2*e)*e,spring:e=>1-Math.cos(e*Math.PI*2.5)*Math.pow(1-e,2.2),bounce:Mt(),elastic:Pt()};function ae(e="top bottom"){let r=e.trim();if(/^\d+(\.\d+)?%$/.test(r))return {element:"top",viewport:r};let[n="top",t="bottom"]=r.split(/\s+/).filter(Boolean);return {element:n,viewport:t}}function Ke(e,r,n,t){switch(t){case "top":return e+n;case "center":return e+n+r/2;case "bottom":return e+n+r;default:return e+n}}function Qe(e,r){if(/^\d+(\.\d+)?%$/.test(e))return r*(parseFloat(e)/100);switch(e){case "top":return 0;case "center":return r/2;case "bottom":return r;default:return r}}function _e(e){let r=e.tagName.toLowerCase();if(r==="rect"){let n=parseFloat(e.getAttribute("width")??"0"),t=parseFloat(e.getAttribute("height")??"0");return 2*(n+t)}if(r==="circle"){let n=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*n}return e.getTotalLength()}function $t(e,r,n){return Math.min(n,Math.max(r,e))}function K(e,r,n,t){return n===r?0:$t((e-r)/(n-r)*t,0,1)}function pe(e,r,n,t,u){let o=Ke(e.top,e.height,r,t.element)-Qe(t.viewport,n),f=Ke(e.top,e.height,r,u.element)-Qe(u.viewport,n);return {tStart:o,tEnd:f}}function et(e){let r=/^#([a-f\d])([a-f\d])([a-f\d])$/i.exec(e);if(r)return [parseInt(r[1]+r[1],16),parseInt(r[2]+r[2],16),parseInt(r[3]+r[3],16)];let n=/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(n)return [parseInt(n[1],16),parseInt(n[2],16),parseInt(n[3],16)];let t=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(e);return t?[parseInt(t[1]),parseInt(t[2]),parseInt(t[3])]:null}function Fe(e,r,n){let t=et(e),u=et(r);return !t||!u?e:`rgb(${Math.round(t[0]+(u[0]-t[0])*n)},${Math.round(t[1]+(u[1]-t[1])*n)},${Math.round(t[2]+(u[2]-t[2])*n)})`}var tt={sketch:{easing:"ease-in",stagger:.1,speed:.9,fade:false},reveal:{easing:"ease-out",fade:true,speed:1.2,once:true},typewriter:{easing:"linear",stagger:.05,speed:1.5},cinematic:{easing:"ease-in-out",fade:true,speed:.75},spring:{easing:"spring",speed:1.1}};function rt(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}var nt={linear:"linear","ease-in":"ease-in","ease-out":"ease-out","ease-in-out":"ease-in-out"},Lt=0;function Ct(){return typeof CSS<"u"&&typeof CSS.supports=="function"&&CSS.supports("animation-timeline: view()")}function kt(e){let r=e.getAttribute("stroke"),n=e.getAttribute("fill");!r||r==="none"?rt("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&rt("Element has a fill \u2014 it may obscure the stroke animation.",e);}function It(e,r,n){let t=document.createElement("div");t.setAttribute("data-svg-scroll-draw-debug",""),t.style.cssText="position:fixed;pointer-events:none;z-index:9999;font-family:monospace;font-size:11px;top:0;left:0;right:0;bottom:0;";function u(){let o=n==="x"?window.scrollX:window.scrollY,f=e-o,l=r-o,c=n==="x";t.innerHTML=`
|
|
2
|
+
<div style="position:absolute;${c?`left:${f}px;top:0;bottom:0;border-left:2px dashed #22c55e;`:`top:${f}px;left:0;right:0;border-top:2px dashed #22c55e;`}padding:2px 6px;color:#22c55e;background:rgba(0,0,0,.6)">\u25B6 start</div>
|
|
3
|
+
<div style="position:absolute;${c?`left:${l}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${l}px;left:0;right:0;border-top:2px dashed #ef4444;`}padding:2px 6px;color:#ef4444;background:rgba(0,0,0,.6)">\u25A0 end</div>`;}return document.body.appendChild(t),window.addEventListener("scroll",u,{passive:true}),u(),t}function Ye(e,r,n){let t=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),u=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,o=>{let f=parseFloat(o),l=t[u++]??f;return String(+(f+(l-f)*n).toFixed(4))})}function st(e,r={}){if(typeof window>"u")return {destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};let{preset:n,...t}=r,u=n?{...tt[n],...t}:t,o=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:f="path, polyline, line, polygon, rect, circle",speed:l=1,fade:c=false,easing:y="linear",trigger:$={},stagger:B=0,direction:S="forward",once:Q=false,debug:ye=false,axis:R="y",scrollContainer:ee,autoReverse:te=false,delay:q=0,strokeColor:x,strokeWidth:A,fillOpacity:w,waypoints:b,velocityScale:C=false,threshold:k=0,rootMargin:G="0px",repeat:L=0,repeatDelay:N=0,morphTo:M,clip:z,autoplay:re=false,duration:D=1e3,native:W=true,onProgress:d,onStart:P,onComplete:g,onEnter:h,onLeave:X,onEnterBack:Se,onLeaveBack:be}=u,we=z===true?"left":typeof z=="string"?z:false,de=typeof y=="function"?y:ie[y]??ie.linear,Ne=ae($.start??"top bottom"),ke=ae($.end??"bottom top"),U=typeof ee=="string"?document.querySelector(ee):ee??null,i=Array.isArray(x)?x[0]:null,p=Array.isArray(x)?x[1]:typeof x=="string"?x:null,Y=Array.isArray(A)?A[0]:null,H=Array.isArray(A)?A[1]:typeof A=="number"?A:null,Z=Array.isArray(w)?w[0]:null,se=Array.isArray(w)?w[1]:typeof w=="number"?w:null;function J(s){let a=s*100;switch(we){case "right":return `inset(0 0 0 ${100-a}%)`;case "top":return `inset(0 0 ${100-a}% 0)`;case "bottom":return `inset(${100-a}% 0 0 0)`;case "center":return `circle(${s*150}% at 50% 50%)`;default:return `inset(0 ${100-a}% 0 0)`}}let _=we?[]:Array.from(e.querySelectorAll(f)),I=[],me=[],ge=0,Te=0,oe=false,he=false,ne=0,He=false,ve=-1,Re=-1,le=false,Le=0,xe=0,Ae,Be=null,Me=new Set,ze=-1,Ue=performance.now(),Ie=NaN;function De(){return U?R==="x"?U.scrollLeft:U.scrollTop:R==="x"?window.scrollX:window.scrollY}function Ze(){return U?R==="x"?U.clientWidth:U.clientHeight:R==="x"?window.innerWidth:window.innerHeight}function Je(){let s=e.getBoundingClientRect(),a,E,j;if(U){let ue=U.getBoundingClientRect();a=R==="x"?s.left-ue.left+U.scrollLeft:s.top-ue.top+U.scrollTop,E=R==="x"?s.width:s.height,j=De();}else a=R==="x"?s.left:s.top,E=R==="x"?s.width:s.height,j=De();let ce=pe({top:a,height:E},j,Ze(),Ne,ke);ge=ce.tStart,Te=ce.tEnd,ye&&process.env.NODE_ENV!=="production"&&(Be?.remove(),Be=It(ge,Te,R));}function St(s,a){if(e.style.setProperty("--scroll-draw-progress",String(s)),we){let E=a==="reverse"?1-s:s;e.style.clipPath=J(E);return}_.forEach((E,j)=>{E.style.strokeDashoffset=a==="reverse"?`${I[j]*s}`:`${I[j]*(1-s)}`,c&&(E.style.opacity=a==="reverse"?`${1-s}`:`${s}`),i&&p?E.style.stroke=Fe(i,p,s):p&&(E.style.stroke=p),Y!==null&&H!==null?E.style.strokeWidth=`${Y+(H-Y)*s}`:H!==null&&(E.style.strokeWidth=`${H}`),Z!==null&&se!==null?E.style.fillOpacity=`${Z+(se-Z)*s}`:se!==null&&(E.style.fillOpacity=`${se}`),M&&E.tagName.toLowerCase()==="path"&&me[j]&&E.setAttribute("d",Ye(me[j],M,s));});}function Ve(){if(e.style.setProperty("--scroll-draw-progress","0"),we){e.style.clipPath=J(0);return}_.forEach((s,a)=>{s.style.strokeDasharray=`${I[a]}`,s.style.strokeDashoffset=S==="reverse"?"0":`${I[a]}`,c?s.style.opacity=S==="reverse"?"1":"0":s.style.opacity="",i&&(s.style.stroke=i),Y!==null&&(s.style.strokeWidth=`${Y}`),Z!==null&&(s.style.fillOpacity=`${Z}`),M&&s.tagName.toLowerCase()==="path"&&me[a]&&s.setAttribute("d",me[a]);});}if(_.forEach(s=>{kt(s);let a=_e(s);I.push(a),s.tagName.toLowerCase()==="path"?me.push(s.getAttribute("d")??""):me.push(""),o?(s.style.strokeDasharray=`${a}`,s.style.strokeDashoffset=S==="reverse"?`${a}`:"0",c&&(s.style.opacity="1"),p&&(s.style.stroke=p),H!==null&&(s.style.strokeWidth=`${H}`),se!==null&&(s.style.fillOpacity=`${se}`),M&&s.tagName.toLowerCase()==="path"&&s.setAttribute("d",M)):(s.style.strokeDasharray=`${a}`,s.style.strokeDashoffset=S==="reverse"?"0":`${a}`,c?s.style.opacity=S==="reverse"?"1":"0":s.style.opacity="",i&&(s.style.stroke=i),Y!==null&&(s.style.strokeWidth=`${Y}`),Z!==null&&(s.style.fillOpacity=`${Z}`));}),we){if(o)return e.style.clipPath=J(1),g?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};e.style.clipPath=J(0);}else if(o)return g?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};function xt(){return !(W===false||!Ct()||!_.length||typeof y!="string"||!(y in nt)||we||R!=="y"||U||l!==1||B!==0||Q||te||C!==false||M||b||L||q>0||d||P||g||h||X||Se||be||x!=null||A!=null||w!=null||($.start??"top bottom").trim()!=="top bottom"||($.end??"bottom top").trim()!=="bottom top")}function Tt(){let s=`svg-scroll-draw-${++Lt}`,a=S==="reverse"?"0":"var(--ssd-len)",E=S==="reverse"?"var(--ssd-len)":"0",j=`stroke-dashoffset:${a};`,ce=`stroke-dashoffset:${E};`;c&&(j+=`opacity:${S==="reverse"?1:0};`,ce+=`opacity:${S==="reverse"?0:1};`);let ue=document.createElement("style");ue.setAttribute("data-svg-scroll-draw",""),ue.textContent=`@keyframes ${s}{from{${j}}to{${ce}}}.${s}{animation-name:${s};animation-duration:auto;animation-timing-function:${nt[y]};animation-fill-mode:both;animation-timeline:view();animation-range:cover 0% cover 100%;}`,document.head.appendChild(ue);function fe(m,T){m.style.setProperty("--ssd-len",String(I[T])),m.style.strokeDasharray=`${I[T]}`,m.style.strokeDashoffset="",m.style.opacity="",m.style.animationPlayState="",m.classList.add(s);}_.forEach(fe);let v=false,O=-1;function F(){if(O>=0)return O;let m=e.getBoundingClientRect(),{tStart:T,tEnd:V}=pe({top:m.top,height:m.height},De(),Ze(),Ne,ke);return de(K(De(),T,V,l))}return {destroy(){_.forEach(m=>{m.classList.remove(s),m.style.removeProperty("--ssd-len"),m.style.animationPlayState="";}),ue.remove();},replay(){v=false,O=-1,_.forEach(fe);},pause(){v=true,_.forEach(m=>{m.style.animationPlayState="paused";});},resume(){v&&(v=false,_.forEach(m=>{m.style.animationPlayState="running";}));},seek(m){let T=Math.min(1,Math.max(0,m));O=T,v=true,_.forEach((V,Ce)=>{V.classList.remove(s),V.style.strokeDashoffset=S==="reverse"?`${I[Ce]*T}`:`${I[Ce]*(1-T)}`,c&&(V.style.opacity=S==="reverse"?`${1-T}`:`${T}`);});},getProgress(){return F()}}}if(xt())return Tt();function At(){let s=Math.max(1,D),a=0,E=0;function j(F){let m=true;if(we){let T=Math.min(1,Math.max(0,F/s)),V=de(T);Le=V,e.style.setProperty("--scroll-draw-progress",String(V)),e.style.clipPath=J(S==="reverse"?1-V:V),d?.(V),T<1&&(m=false);}else _.forEach((T,V)=>{let Ce=V*B*s,Oe=Math.min(1,Math.max(0,(F-Ce)/s)),Ee=de(Oe);T.style.strokeDashoffset=S==="reverse"?`${I[V]*Ee}`:`${I[V]*(1-Ee)}`,c&&(T.style.opacity=S==="reverse"?`${1-Ee}`:`${Ee}`),i&&p?T.style.stroke=Fe(i,p,Ee):p&&(T.style.stroke=p),Y!==null&&H!==null?T.style.strokeWidth=`${Y+(H-Y)*Ee}`:H!==null&&(T.style.strokeWidth=`${H}`),Z!==null&&se!==null?T.style.fillOpacity=`${Z+(se-Z)*Ee}`:se!==null&&(T.style.fillOpacity=`${se}`),M&&T.tagName.toLowerCase()==="path"&&me[V]&&T.setAttribute("d",Ye(me[V],M,Ee)),V===0&&(d?.(Ee),e.style.setProperty("--scroll-draw-progress",String(Ee))),Oe<1&&(m=false);});if(b){let T=Math.min(1,Math.max(0,F/s)),V=de(T);for(let Ce in b){let Oe=parseFloat(Ce);V>=Oe&&!Me.has(Oe)&&(Me.add(Oe),b[Ce]?.());}}return m}function ce(F){if(le)return;let m=F-a;he||(he=true,P?.());let T=j(m);if(T&&!oe){oe=true,j(s*(1+Math.max(0,_.length-1)*B)),g?.(),xe<(L==="infinite"?1/0:L??0)&&(xe++,Ae=setTimeout(()=>{a=performance.now(),he=false,oe=false,Me.clear(),Ve(),ne=requestAnimationFrame(ce);},N));return}T||(ne=requestAnimationFrame(ce));}function ue(){cancelAnimationFrame(ne),clearTimeout(Ae),a=performance.now(),E=0,le=false,he=false,oe=false,xe=0,Me.clear(),Ve(),ne=requestAnimationFrame(ce);}let fe=new IntersectionObserver(F=>{F.forEach(m=>{m.isIntersecting&&!(Q&&oe)?ue():!m.isIntersecting&&!Q&&!oe&&(cancelAnimationFrame(ne),clearTimeout(Ae),a=null);});},{root:U??null,threshold:k,rootMargin:G}),v;function O(){clearTimeout(v),v=setTimeout(()=>{_.forEach((F,m)=>{I[m]=_e(F),F.style.strokeDasharray=`${I[m]}`;});},150);}return window.addEventListener("resize",O),window.addEventListener("orientationchange",O),q>0?setTimeout(()=>fe.observe(e),q):fe.observe(e),{destroy(){cancelAnimationFrame(ne),clearTimeout(Ae),fe.disconnect(),window.removeEventListener("resize",O),window.removeEventListener("orientationchange",O),clearTimeout(v);},replay(){xe=0,ue();},pause(){le||(le=true,E=performance.now()-a,cancelAnimationFrame(ne));},resume(){le&&(le=false,a=performance.now()-E,ne=requestAnimationFrame(ce));},seek(F){let m=Math.min(1,Math.max(0,F));Le=m,le=true,E=m*s,a=performance.now()-E,cancelAnimationFrame(ne),j(E);},getProgress(){return Le}}}if(re)return At();Je();function qe(){if(!He||le)return;let s=performance.now(),a=De(),E=l;if(C!==false){let v=s-Ue,O=v>0?Math.abs(a-(ze<0?a:ze))/v:0;E=l*Math.max(.2,1+O*(typeof C=="number"?C:1)*.04);}ze=a,Ue=s;let j=te?Re===-1||a>=Re?"forward":"reverse":S;Re=a;let ce=Te-ge,ue=true,fe=ce===0?0:(a-ge)/ce;if(isNaN(Ie)||(Ie<=0&&fe>0?h?.():Ie>0&&fe<=0&&be?.(),Ie<1&&fe>=1?X?.():Ie>=1&&fe<1&&Se?.()),Ie=fe,we){let v=de(K(a,ge,Te,E));Q&&!te&&(ve=Math.max(ve,v),v=ve),Le=v,e.style.setProperty("--scroll-draw-progress",String(v));let O=j==="reverse"?1-v:v;e.style.clipPath=J(O),d?.(v),!he&&K(a,ge,Te,E)>0&&(he=true,P?.()),v>=1&&!oe?(oe=true,g?.(),xe<(L==="infinite"?1/0:L??0)&&(xe++,Ae=setTimeout(()=>{ve=-1,he=false,oe=false,e.style.clipPath=J(0);},N))):v<1&&!Q&&(oe=false),ne=requestAnimationFrame(qe);return}if(_.forEach((v,O)=>{let F=O*B*ce,m=de(K(a,ge+F,Te+F,E));Q&&!te&&(ve=Math.max(ve,m),m=ve),Le=m,v.style.strokeDashoffset=j==="reverse"?`${I[O]*m}`:`${I[O]*(1-m)}`,c&&(v.style.opacity=j==="reverse"?`${1-m}`:`${m}`),i&&p?v.style.stroke=Fe(i,p,m):p&&(v.style.stroke=p),Y!==null&&H!==null?v.style.strokeWidth=`${Y+(H-Y)*m}`:H!==null&&(v.style.strokeWidth=`${H}`),Z!==null&&se!==null?v.style.fillOpacity=`${Z+(se-Z)*m}`:se!==null&&(v.style.fillOpacity=`${se}`),M&&v.tagName.toLowerCase()==="path"&&me[O]&&v.setAttribute("d",Ye(me[O],M,m)),O===0&&(d?.(m),e.style.setProperty("--scroll-draw-progress",String(m))),m<1&&(ue=false);}),b){let v=de(K(a,ge,Te,E));for(let O in b){let F=parseFloat(O);v>=F&&!Me.has(F)&&(Me.add(F),b[O]?.());}}!he&&K(a,ge,Te,E)>0&&(he=true,P?.()),ue&&!oe?(oe=true,g?.(),xe<(L==="infinite"?1/0:L??0)&&(xe++,Ae=setTimeout(()=>{ve=-1,he=false,oe=false,Me.clear(),Ve();},N))):!ue&&!Q&&(oe=false),ne=requestAnimationFrame(qe);}let Ge=new IntersectionObserver(s=>{s.forEach(a=>{He=a.isIntersecting,He&&!le?ne=requestAnimationFrame(qe):cancelAnimationFrame(ne);});},{root:U??null,threshold:k,rootMargin:G}),Xe;function We(){clearTimeout(Xe),Xe=setTimeout(()=>{_.forEach((s,a)=>{I[a]=_e(s),s.style.strokeDasharray=`${I[a]}`;}),Je();},150);}return window.addEventListener("resize",We),window.addEventListener("orientationchange",We),q>0?setTimeout(()=>Ge.observe(e),q):Ge.observe(e),{destroy(){cancelAnimationFrame(ne),clearTimeout(Ae),Ge.disconnect(),window.removeEventListener("resize",We),window.removeEventListener("orientationchange",We),clearTimeout(Xe),Be?.remove();},replay(){ve=-1,Re=-1,ze=-1,he=false,oe=false,xe=0,le=false,Me.clear(),clearTimeout(Ae),Ve();},pause(){le=true,cancelAnimationFrame(ne);},resume(){le&&(le=false,He&&(ne=requestAnimationFrame(qe)));},seek(s){let a=Math.min(1,Math.max(0,s));Le=a,ve=a,le=true,cancelAnimationFrame(ne),St(a,S);},getProgress(){return Le}}}var ot=new Map;function Pe(e,r){ot.set(e,r);}function $e(e){ot.delete(e);}function Ot(e){return e.startsWith("#")||e.startsWith("rgb")||e.startsWith("hsl")}function it(e){let r=[],n=/([\w]+)\(([^)]*)\)/g,t;for(;(t=n.exec(e))!==null;){let u=[],o=[],f=t[2].trim();if(f)for(let l of f.split(/[\s,]+/)){let c=l.match(/^([-+]?[\d.eE]+)(.*)$/);u.push(c?parseFloat(c[1]):0),o.push(c?c[2]:"");}r.push({fn:t[1],nums:u,units:o});}return r}function Ft(e,r,n){let t=it(e),u=it(r);return t.length===0||t.length!==u.length?n<1?e:r:t.map((o,f)=>{let l=u[f];return o.fn!==l.fn||o.nums.length!==l.nums.length?n<1?`${o.fn}(${o.nums.map((c,y)=>`${c}${o.units[y]}`).join(", ")})`:`${l.fn}(${l.nums.map((c,y)=>`${c}${l.units[y]}`).join(", ")})`:`${o.fn}(${o.nums.map((c,y)=>`${c+(l.nums[y]-c)*n}${o.units[y]}`).join(", ")})`}).join(" ")}function at(e,r,n){if(typeof e=="number"&&typeof r=="number")return String(e+(r-e)*n);let t=String(e),u=String(r);if(Ot(t))return Fe(t,u,n);if(t.includes("("))return Ft(t,u,n);let o=t.match(/^([-+]?[\d.]+)(.*)$/),f=u.match(/^([-+]?[\d.]+)(.*)$/);if(o&&f){let l=parseFloat(o[1]),c=parseFloat(f[1]);return `${l+(c-l)*n}${o[2]||f[2]}`}return n<1?t:u}function Nt(e){return e.replace(/([A-Z])/g,r=>`-${r.toLowerCase()}`)}var lt={linear:"linear","ease-in":"ease-in","ease-out":"ease-out","ease-in-out":"ease-in-out"},Dt=new Set(["opacity","transform","background-color","color","filter","scale","translate","rotate"]),Ht=0;function Rt(){return typeof CSS<"u"&&typeof CSS.supports=="function"&&CSS.supports("animation-timeline: view()")}function ct(e,r){let n={destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};if(typeof window>"u")return n;let{props:t,trigger:u={},easing:o="ease-out",speed:f=1,once:l=false,axis:c="y",scrollContainer:y,native:$=true,onProgress:B,onComplete:S,onEnter:Q,onLeave:ye,onEnterBack:R,onLeaveBack:ee}=r,te=window.matchMedia("(prefers-reduced-motion: reduce)").matches,q=typeof o=="function"?o:ie[o]??ie["ease-out"],x=ae(u.start??"top bottom"),A=ae(u.end??"bottom top"),w=typeof y=="string"?document.querySelector(y):y??null,b=Object.entries(t).map(([i,p])=>({prop:Nt(i),from:Array.isArray(p)?p[0]:"",to:Array.isArray(p)?p[1]:p}));function C(){let i=window.getComputedStyle(e);for(let p of b)p.from===""&&(p.from=i.getPropertyValue(p.prop).trim()||"0");}function k(){for(let i of b)e.style.setProperty(i.prop,String(i.to));}if(te)return k(),S?.(),n;C();function G(){if(!$||!Rt()||typeof o!="string"||!(o in lt)||c!=="y"||w||l||f!==1||B||S||Q||ye||R||ee||(u.start??"top bottom").trim()!=="top bottom"||(u.end??"bottom top").trim()!=="bottom top")return false;for(let i of b)if(!Dt.has(i.prop))return false;return true}function L(){let i=`ssd-a-${++Ht}`,p=b.map(J=>`${J.prop}:${J.from}`).join(";"),Y=b.map(J=>`${J.prop}:${J.to}`).join(";"),H=document.createElement("style");H.setAttribute("data-ssd-animate",""),H.textContent=`@keyframes ${i}{from{${p}}to{${Y}}}.${i}{animation-name:${i};animation-duration:auto;animation-timing-function:${lt[o]};animation-fill-mode:both;animation-timeline:view();animation-range:cover 0% cover 100%;}`,document.head.appendChild(H),e.classList.add(i);let Z=()=>c==="x"?window.scrollX:window.scrollY,se=()=>c==="x"?window.innerWidth:window.innerHeight;return {destroy(){e.classList.remove(i),H.remove();},replay(){e.classList.remove(i),e.offsetWidth,e.classList.add(i);},pause(){e.style.animationPlayState="paused";},resume(){e.style.animationPlayState="";},seek(J){let _=Math.min(1,Math.max(0,J));e.classList.remove(i);for(let I of b)e.style.setProperty(I.prop,at(I.from,I.to,_));},getProgress(){let J=e.getBoundingClientRect(),_=Z(),I=se(),{tStart:me,tEnd:ge}=pe({top:J.top,height:J.height},_,I,x,A);return q(K(_,me,ge,f))}}}if(G())return L();let N=0,M=0,z=0,re=false,D=false,W=-1,d=0,P=false,g=NaN,h=()=>w?c==="x"?w.scrollLeft:w.scrollTop:c==="x"?window.scrollX:window.scrollY,X=()=>w?c==="x"?w.clientWidth:w.clientHeight:c==="x"?window.innerWidth:window.innerHeight;function Se(){let i=e.getBoundingClientRect(),p,Y;if(w){let Z=w.getBoundingClientRect();p=c==="x"?i.left-Z.left+w.scrollLeft:i.top-Z.top+w.scrollTop,Y=c==="x"?i.width:i.height;}else p=c==="x"?i.left:i.top,Y=c==="x"?i.width:i.height;let H=pe({top:p,height:Y},h(),X(),x,A);N=H.tStart,M=H.tEnd;}function be(i){e.style.setProperty("--scroll-draw-progress",String(i));for(let p of b)e.style.setProperty(p.prop,at(p.from,p.to,i));B?.(i);}function we(i){if(isNaN(g)){g=i;return}g<=0&&i>0?Q?.():g>0&&i<=0&&ee?.(),g<1&&i>=1?ye?.():g>=1&&i<1&&R?.(),g=i;}function de(){if(!re||D)return;let i=M===N?0:(h()-N)/(M-N);we(i);let p=q(K(h(),N,M,f));l&&(W=Math.max(W,p),p=W),d=p,be(p),p>=1&&!P?(P=true,S?.()):p<1&&!l&&(P=false),z=requestAnimationFrame(de);}Se();{let i=q(K(h(),N,M,f));l&&i>0&&(W=i),d=i,be(i);}let Ne=new IntersectionObserver(i=>{i.forEach(p=>{re=p.isIntersecting,re&&!D?z=requestAnimationFrame(de):cancelAnimationFrame(z);});},{root:w??null}),ke;function U(){clearTimeout(ke),ke=setTimeout(Se,150);}return window.addEventListener("resize",U),window.addEventListener("orientationchange",U),Ne.observe(e),Pe(e,{type:"animate",getProgress:()=>d,getTrigger:()=>({tStart:N,tEnd:M})}),{destroy(){cancelAnimationFrame(z),Ne.disconnect(),window.removeEventListener("resize",U),window.removeEventListener("orientationchange",U),clearTimeout(ke),$e(e);},replay(){W=-1,P=false,d=0,D=false,be(0);},pause(){D=true,cancelAnimationFrame(z);},resume(){D&&(D=false,re&&(z=requestAnimationFrame(de)));},seek(i){let p=Math.min(1,Math.max(0,i));d=p,W=p,D=true,cancelAnimationFrame(z),be(p);},getProgress(){return d}}}var je={destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};function ut(e,r){if(typeof window>"u")return je;let n=typeof e=="string"?document.querySelector(e):e;if(!n)return process.env.NODE_ENV!=="production"&&console.warn("[svg-scroll-draw] scrollCounter: element not found:",e),je;let t=n,{from:u=0,to:o,format:f,easing:l="ease-out",trigger:c={},once:y=true,decimals:$,onComplete:B}=r,S=$!==void 0?d=>d.toFixed($):f??(d=>String(Math.round(d))),Q=typeof l=="function"?l:ie[l]??ie["ease-out"],ye=ae(c.start??"top 80%"),R=ae(c.end??"top 20%");if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return t.textContent=S(o),B?.(),je;t.textContent=S(u);let te=0,q=0,x=0,A=false,w=false,b=-1,C=0,k=false,G=()=>window.scrollY,L=()=>window.innerHeight;function N(){let d=t.getBoundingClientRect(),P=pe({top:d.top,height:d.height},G(),L(),ye,R);te=P.tStart,q=P.tEnd;}function M(d){t.textContent=S(u+(o-u)*d),t.style.setProperty("--scroll-draw-progress",String(d));}function z(){if(!A||w)return;let d=Q(K(G(),te,q,1));y&&(b=Math.max(b,d),d=b),C=d,M(d),d>=1&&!k?(k=true,B?.()):d<1&&!y&&(k=false),x=requestAnimationFrame(z);}N();{let d=Q(K(G(),te,q,1));y&&d>0&&(b=d),C=d,M(d);}let re=new IntersectionObserver(d=>{d.forEach(P=>{A=P.isIntersecting,A&&!w?x=requestAnimationFrame(z):cancelAnimationFrame(x);});}),D;function W(){clearTimeout(D),D=setTimeout(N,150);}return window.addEventListener("resize",W),window.addEventListener("orientationchange",W),re.observe(t),Pe(t,{type:"counter",getProgress:()=>C,getTrigger:()=>({tStart:te,tEnd:q})}),{destroy(){cancelAnimationFrame(x),re.disconnect(),window.removeEventListener("resize",W),window.removeEventListener("orientationchange",W),clearTimeout(D),$e(t);},replay(){b=-1,k=false,C=0,w=false,M(0);},pause(){w=true,cancelAnimationFrame(x);},resume(){w&&(w=false,A&&(x=requestAnimationFrame(z)));},seek(d){let P=Math.min(1,Math.max(0,d));C=P,b=P,w=true,cancelAnimationFrame(x),M(P);},getProgress(){return C}}}var mt={destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};function ft(e,r={}){if(typeof window>"u")return mt;let n=typeof e=="string"?document.querySelector(e):e;if(!n||n.tagName.toLowerCase()!=="video")return process.env.NODE_ENV!=="production"&&console.warn("[svg-scroll-draw] scrollVideo: <video> element not found:",e),mt;let t=n,{trigger:u={},easing:o="linear",once:f=false,axis:l="y",preload:c="auto",onReady:y,onComplete:$,onProgress:B}=r,S=window.matchMedia("(prefers-reduced-motion: reduce)").matches,Q=typeof o=="function"?o:ie[o]??ie.linear,ye=ae(u.start??"top top"),R=ae(u.end??"bottom top");t.pause(),t.hasAttribute("preload")||(t.preload=c);let ee=r.from??0,te=r.to,q=0,x=0,A=0,w=false,b=false,C=-1,k=0,G=false,L=false,N=()=>l==="x"?window.scrollX:window.scrollY,M=()=>l==="x"?window.innerWidth:window.innerHeight;function z(){let h=t.getBoundingClientRect(),X=l==="x"?h.left:h.top,Se=l==="x"?h.width:h.height,be=pe({top:X,height:Se},N(),M(),ye,R);q=be.tStart,x=be.tEnd;}function re(h){if(!L)return;let X=te??t.duration??0;t.currentTime=ee+(X-ee)*h,t.style.setProperty("--scroll-draw-progress",String(h)),B?.(h);}function D(){if(!w||b||!L)return;let h=Q(K(N(),q,x,1));f&&(C=Math.max(C,h),h=C),k=h,re(h),h>=1&&!G?(G=true,$?.()):h<1&&!f&&(G=false),A=requestAnimationFrame(D);}function W(){if(L=true,te===void 0&&(te=t.duration),S){re(1),y?.();return}z(),y?.(),w&&!b&&(A=requestAnimationFrame(D));}t.readyState>=1?W():t.addEventListener("loadedmetadata",W,{once:true}),L||z();let d=new IntersectionObserver(h=>{h.forEach(X=>{w=X.isIntersecting,w&&!b&&L?A=requestAnimationFrame(D):cancelAnimationFrame(A);});}),P;function g(){clearTimeout(P),P=setTimeout(z,150);}return window.addEventListener("resize",g),window.addEventListener("orientationchange",g),d.observe(t),Pe(t,{type:"video",getProgress:()=>k,getTrigger:()=>({tStart:q,tEnd:x})}),{destroy(){cancelAnimationFrame(A),d.disconnect(),t.removeEventListener("loadedmetadata",W),window.removeEventListener("resize",g),window.removeEventListener("orientationchange",g),clearTimeout(P),$e(t);},replay(){C=-1,G=false,k=0,b=false,re(0);},pause(){b=true,cancelAnimationFrame(A);},resume(){b&&(b=false,w&&L&&(A=requestAnimationFrame(D)));},seek(h){let X=Math.min(1,Math.max(0,h));k=X,C=X,b=true,cancelAnimationFrame(A),re(X);},getProgress(){return k}}}function gt(e){let r=e.textContent??"";return e.textContent="",r.split(/(\s+)/).filter(Boolean).map(n=>{let t=document.createElement("span");return t.setAttribute("aria-hidden","true"),/^\s+$/.test(n)?(t.textContent=n,t.style.whiteSpace="pre"):(t.textContent=n,t.style.display="inline-block"),e.appendChild(t),/^\s+$/.test(n)?null:t}).filter(n=>n!==null)}function zt(e){let r=e.textContent??"";return e.textContent="",r.split("").map(n=>{let t=document.createElement("span");return t.setAttribute("aria-hidden","true"),t.textContent=n,n===" "?t.style.whiteSpace="pre":t.style.display="inline-block",e.appendChild(t),n===" "?null:t}).filter(n=>n!==null)}function pt(e){let r=gt(e),n=new Map;for(let o of r){let f=o.offsetTop;n.has(f)||n.set(f,[]),n.get(f).push(o);}let t=[],u=Array.from(n.keys()).sort((o,f)=>o-f);for(let o of u){let f=n.get(o),l=document.createElement("span");l.setAttribute("aria-hidden","true"),l.style.display="inline-block";for(let c of f)l.appendChild(c);t.push(l);}e.textContent="";for(let o of t)e.appendChild(o),e.appendChild(document.createTextNode(" "));return t}function Vt(e,r,n,t){if(n<=1||t===0)return e;let u=(n-1)*t,o=r*t,f=o+(1-u);return f<=o?e>=o?1:0:Math.min(1,Math.max(0,(e-o)/(f-o)))}function qt(e,r){let n=[];if(r?.y!==void 0&&n.push(`translateY(${r.y*(1-e)}px)`),r?.x!==void 0&&n.push(`translateX(${r.x*(1-e)}px)`),r?.rotate!==void 0&&n.push(`rotate(${r.rotate*(1-e)}deg)`),r?.scale!==void 0){let t=r.scale+(1-r.scale)*e;n.push(`scale(${t})`);}return n.join(" ")||""}var dt={destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};function ht(e,r={}){if(typeof window>"u")return dt;let n=typeof e=="string"?document.querySelector(e):e;if(!n)return process.env.NODE_ENV!=="production"&&console.warn("[svg-scroll-draw] scrollText: element not found:",e),dt;let t=n,{split:u="words",stagger:o=.04,easing:f="ease-out",from:l={opacity:0,y:24},trigger:c={},once:y=true,onComplete:$}=r,B=window.matchMedia("(prefers-reduced-motion: reduce)").matches,S=typeof f=="function"?f:ie[f]??ie["ease-out"],Q=ae(c.start??"top 85%"),ye=ae(c.end??"top 40%"),R=t.innerHTML;t.setAttribute("aria-label",t.textContent??"");let ee;u==="chars"?ee=zt(t):u==="lines"?ee=pt(t):ee=gt(t);let te=ee.length;function q(g,h){l?.opacity!==void 0&&(g.style.opacity=String(l.opacity+(1-l.opacity)*h));let X=qt(h,l);X&&(g.style.transform=X);}function x(g){t.style.setProperty("--scroll-draw-progress",String(g)),ee.forEach((h,X)=>{let Se=S(Vt(g,X,te,o));q(h,Se);});}if(B)return x(1),$?.(),{destroy(){t.innerHTML=R,t.removeAttribute("aria-label");},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};x(0);let A=0,w=0,b=0,C=false,k=false,G=-1,L=0,N=false,M=()=>window.scrollY,z=()=>window.innerHeight;function re(){let g=t.getBoundingClientRect(),h=pe({top:g.top,height:g.height},M(),z(),Q,ye);A=h.tStart,w=h.tEnd;}function D(){if(!C||k)return;let g=K(M(),A,w,1);y&&(G=Math.max(G,g),g=G),L=g,x(g),g>=1&&!N?(N=true,$?.()):g<1&&!y&&(N=false),b=requestAnimationFrame(D);}re();let W=new IntersectionObserver(g=>{g.forEach(h=>{C=h.isIntersecting,C&&!k?b=requestAnimationFrame(D):cancelAnimationFrame(b);});}),d;function P(){clearTimeout(d),d=setTimeout(()=>{if(u==="lines"){let g=L;t.innerHTML=R,t.setAttribute("aria-label",t.textContent??""),ee=pt(t),x(g);}re();},150);}return window.addEventListener("resize",P),window.addEventListener("orientationchange",P),W.observe(t),Pe(t,{type:"text",getProgress:()=>L,getTrigger:()=>({tStart:A,tEnd:w})}),{destroy(){cancelAnimationFrame(b),W.disconnect(),window.removeEventListener("resize",P),window.removeEventListener("orientationchange",P),clearTimeout(d),t.innerHTML=R,t.removeAttribute("aria-label"),$e(t);},replay(){G=-1,N=false,L=0,k=false,x(0);},pause(){k=true,cancelAnimationFrame(b);},resume(){k&&(k=false,C&&(b=requestAnimationFrame(D)));},seek(g){let h=Math.min(1,Math.max(0,g));L=h,G=h,k=true,cancelAnimationFrame(b),x(h);},getProgress(){return L}}}var yt=class{constructor(){this.instance=null;}init(r,n={}){return this.destroy(),this.instance=st(r,n),this}replay(){return this.instance?.replay(),this}pause(){return this.instance?.pause(),this}resume(){return this.instance?.resume(),this}seek(r){return this.instance?.seek(r),this}getProgress(){return this.instance?.getProgress()??0}destroy(){return this.instance?.destroy(),this.instance=null,this}},bt=class{constructor(){this.instance=null;}init(r,n){return this.destroy(),this.instance=ct(r,n),this}replay(){return this.instance?.replay(),this}pause(){return this.instance?.pause(),this}resume(){return this.instance?.resume(),this}seek(r){return this.instance?.seek(r),this}getProgress(){return this.instance?.getProgress()??0}destroy(){return this.instance?.destroy(),this.instance=null,this}},wt=class{constructor(){this.instance=null;}init(r,n){return this.destroy(),this.instance=ut(r,n),this}replay(){return this.instance?.replay(),this}pause(){return this.instance?.pause(),this}resume(){return this.instance?.resume(),this}seek(r){return this.instance?.seek(r),this}getProgress(){return this.instance?.getProgress()??0}destroy(){return this.instance?.destroy(),this.instance=null,this}},vt=class{constructor(){this.instance=null;}init(r,n={}){return this.destroy(),this.instance=ft(r,n),this}replay(){return this.instance?.replay(),this}pause(){return this.instance?.pause(),this}resume(){return this.instance?.resume(),this}seek(r){return this.instance?.seek(r),this}getProgress(){return this.instance?.getProgress()??0}destroy(){return this.instance?.destroy(),this.instance=null,this}},Et=class{constructor(){this.instance=null;}init(r,n={}){return this.destroy(),this.instance=ht(r,n),this}replay(){return this.instance?.replay(),this}pause(){return this.instance?.pause(),this}resume(){return this.instance?.resume(),this}seek(r){return this.instance?.seek(r),this}getProgress(){return this.instance?.getProgress()??0}destroy(){return this.instance?.destroy(),this.instance=null,this}};exports.ScrollAnimateRef=bt;exports.ScrollCounterRef=wt;exports.ScrollDrawRef=yt;exports.ScrollTextRef=Et;exports.ScrollVideoRef=vt;
|
package/dist/angular/index.d.mts
CHANGED
|
@@ -71,6 +71,14 @@ interface ScrollDrawOptions {
|
|
|
71
71
|
onProgress?: (alpha: number) => void;
|
|
72
72
|
onStart?: () => void;
|
|
73
73
|
onComplete?: () => void;
|
|
74
|
+
/** Fires when scroll position enters the trigger zone (scrolling forward). */
|
|
75
|
+
onEnter?: () => void;
|
|
76
|
+
/** Fires when scroll position exits the trigger zone at the end (scrolling forward). */
|
|
77
|
+
onLeave?: () => void;
|
|
78
|
+
/** Fires when scroll position re-enters the trigger zone from the end (scrolling back). */
|
|
79
|
+
onEnterBack?: () => void;
|
|
80
|
+
/** Fires when scroll position exits the trigger zone at the start (scrolling back). */
|
|
81
|
+
onLeaveBack?: () => void;
|
|
74
82
|
/**
|
|
75
83
|
* Trigger the animation when the element enters the viewport instead of
|
|
76
84
|
* tying it to scroll position. The draw runs over `duration` milliseconds,
|
|
@@ -119,14 +127,72 @@ interface ScrollDrawInstance {
|
|
|
119
127
|
getProgress: () => number;
|
|
120
128
|
}
|
|
121
129
|
|
|
130
|
+
interface ScrollAnimateOptions {
|
|
131
|
+
props: Record<string, string | number | [string | number, string | number]>;
|
|
132
|
+
trigger?: TriggerConfig;
|
|
133
|
+
easing?: EasingName | ((t: number) => number);
|
|
134
|
+
speed?: number;
|
|
135
|
+
once?: boolean;
|
|
136
|
+
axis?: 'x' | 'y';
|
|
137
|
+
scrollContainer?: string | Element;
|
|
138
|
+
native?: boolean;
|
|
139
|
+
onProgress?: (alpha: number) => void;
|
|
140
|
+
onComplete?: () => void;
|
|
141
|
+
/** Fires when scroll enters the trigger zone (scrolling forward). */
|
|
142
|
+
onEnter?: () => void;
|
|
143
|
+
/** Fires when scroll exits the trigger zone at the end (scrolling forward). */
|
|
144
|
+
onLeave?: () => void;
|
|
145
|
+
/** Fires when scroll re-enters the trigger zone from the end (scrolling back). */
|
|
146
|
+
onEnterBack?: () => void;
|
|
147
|
+
/** Fires when scroll exits the trigger zone at the start (scrolling back). */
|
|
148
|
+
onLeaveBack?: () => void;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
interface ScrollCounterOptions {
|
|
152
|
+
from?: number;
|
|
153
|
+
to: number;
|
|
154
|
+
format?: (value: number) => string;
|
|
155
|
+
easing?: EasingName | ((t: number) => number);
|
|
156
|
+
trigger?: TriggerConfig;
|
|
157
|
+
once?: boolean;
|
|
158
|
+
decimals?: number;
|
|
159
|
+
onComplete?: () => void;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
interface ScrollVideoOptions {
|
|
163
|
+
trigger?: TriggerConfig;
|
|
164
|
+
from?: number;
|
|
165
|
+
to?: number;
|
|
166
|
+
easing?: EasingName | ((t: number) => number);
|
|
167
|
+
once?: boolean;
|
|
168
|
+
axis?: 'x' | 'y';
|
|
169
|
+
preload?: 'auto' | 'metadata';
|
|
170
|
+
onReady?: () => void;
|
|
171
|
+
onComplete?: () => void;
|
|
172
|
+
onProgress?: (alpha: number) => void;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
interface ScrollTextOptions {
|
|
176
|
+
split?: 'chars' | 'words' | 'lines';
|
|
177
|
+
stagger?: number;
|
|
178
|
+
easing?: EasingName | ((t: number) => number);
|
|
179
|
+
from?: {
|
|
180
|
+
opacity?: number;
|
|
181
|
+
y?: number;
|
|
182
|
+
x?: number;
|
|
183
|
+
rotate?: number;
|
|
184
|
+
scale?: number;
|
|
185
|
+
};
|
|
186
|
+
trigger?: TriggerConfig;
|
|
187
|
+
once?: boolean;
|
|
188
|
+
onComplete?: () => void;
|
|
189
|
+
}
|
|
190
|
+
|
|
122
191
|
/**
|
|
123
192
|
* Framework-agnostic class for use in Angular components.
|
|
124
193
|
* No @angular/core dependency required.
|
|
125
194
|
*
|
|
126
195
|
* @example
|
|
127
|
-
* // In your Angular component:
|
|
128
|
-
* import { ScrollDrawRef } from 'svg-scroll-draw/angular';
|
|
129
|
-
*
|
|
130
196
|
* @Component({ template: '<div #container><svg>...</svg></div>' })
|
|
131
197
|
* export class HeroComponent implements AfterViewInit, OnDestroy {
|
|
132
198
|
* @ViewChild('container') containerRef!: ElementRef<HTMLElement>;
|
|
@@ -134,22 +200,141 @@ interface ScrollDrawInstance {
|
|
|
134
200
|
*
|
|
135
201
|
* ngAfterViewInit() {
|
|
136
202
|
* this.draw.init(this.containerRef.nativeElement, {
|
|
137
|
-
* easing: 'ease-out',
|
|
138
|
-
* speed: 1.2,
|
|
139
|
-
* fade: true,
|
|
203
|
+
* easing: 'ease-out', speed: 1.2, fade: true,
|
|
140
204
|
* });
|
|
141
205
|
* }
|
|
142
206
|
*
|
|
143
207
|
* ngOnDestroy() { this.draw.destroy(); }
|
|
144
|
-
*
|
|
145
|
-
* replay() { this.draw.replay(); }
|
|
146
208
|
* }
|
|
147
209
|
*/
|
|
148
210
|
declare class ScrollDrawRef {
|
|
149
211
|
private instance;
|
|
150
212
|
init(element: HTMLElement, options?: ScrollDrawOptions): this;
|
|
151
213
|
replay(): this;
|
|
214
|
+
pause(): this;
|
|
215
|
+
resume(): this;
|
|
216
|
+
seek(p: number): this;
|
|
217
|
+
getProgress(): number;
|
|
218
|
+
destroy(): this;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Animate any CSS property on any element driven by scroll — Angular class-based API.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* @Component({ template: '<div #el>...</div>' })
|
|
225
|
+
* export class CardComponent implements AfterViewInit, OnDestroy {
|
|
226
|
+
* @ViewChild('el') elRef!: ElementRef<HTMLElement>;
|
|
227
|
+
* private animate = new ScrollAnimateRef();
|
|
228
|
+
*
|
|
229
|
+
* ngAfterViewInit() {
|
|
230
|
+
* this.animate.init(this.elRef.nativeElement, {
|
|
231
|
+
* props: { opacity: [0, 1], transform: ['translateY(40px)', 'translateY(0)'] },
|
|
232
|
+
* easing: 'ease-out',
|
|
233
|
+
* once: true,
|
|
234
|
+
* });
|
|
235
|
+
* }
|
|
236
|
+
*
|
|
237
|
+
* ngOnDestroy() { this.animate.destroy(); }
|
|
238
|
+
* }
|
|
239
|
+
*/
|
|
240
|
+
declare class ScrollAnimateRef {
|
|
241
|
+
private instance;
|
|
242
|
+
init(element: HTMLElement, options: ScrollAnimateOptions): this;
|
|
243
|
+
replay(): this;
|
|
244
|
+
pause(): this;
|
|
245
|
+
resume(): this;
|
|
246
|
+
seek(p: number): this;
|
|
247
|
+
getProgress(): number;
|
|
248
|
+
destroy(): this;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Animate a number from `from` to `to` as the element scrolls into view — Angular class-based API.
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* @Component({ template: '<span #counter></span>' })
|
|
255
|
+
* export class StatsComponent implements AfterViewInit, OnDestroy {
|
|
256
|
+
* @ViewChild('counter') counterRef!: ElementRef<HTMLElement>;
|
|
257
|
+
* private counter = new ScrollCounterRef();
|
|
258
|
+
*
|
|
259
|
+
* ngAfterViewInit() {
|
|
260
|
+
* this.counter.init(this.counterRef.nativeElement, {
|
|
261
|
+
* to: 1_250_000,
|
|
262
|
+
* format: n => '$' + Math.round(n).toLocaleString(),
|
|
263
|
+
* once: true,
|
|
264
|
+
* });
|
|
265
|
+
* }
|
|
266
|
+
*
|
|
267
|
+
* ngOnDestroy() { this.counter.destroy(); }
|
|
268
|
+
* }
|
|
269
|
+
*/
|
|
270
|
+
declare class ScrollCounterRef {
|
|
271
|
+
private instance;
|
|
272
|
+
init(element: HTMLElement, options: ScrollCounterOptions): this;
|
|
273
|
+
replay(): this;
|
|
274
|
+
pause(): this;
|
|
275
|
+
resume(): this;
|
|
276
|
+
seek(p: number): this;
|
|
277
|
+
getProgress(): number;
|
|
278
|
+
destroy(): this;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Tie a <video> element's currentTime to scroll — Angular class-based API.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* @Component({ template: '<video #vid src="/hero.mp4" muted playsinline preload="auto"></video>' })
|
|
285
|
+
* export class HeroVideoComponent implements AfterViewInit, OnDestroy {
|
|
286
|
+
* @ViewChild('vid') vidRef!: ElementRef<HTMLVideoElement>;
|
|
287
|
+
* private video = new ScrollVideoRef();
|
|
288
|
+
*
|
|
289
|
+
* ngAfterViewInit() {
|
|
290
|
+
* this.video.init(this.vidRef.nativeElement, {
|
|
291
|
+
* trigger: { start: 'top top', end: 'bottom top' },
|
|
292
|
+
* });
|
|
293
|
+
* }
|
|
294
|
+
*
|
|
295
|
+
* ngOnDestroy() { this.video.destroy(); }
|
|
296
|
+
* }
|
|
297
|
+
*/
|
|
298
|
+
declare class ScrollVideoRef {
|
|
299
|
+
private instance;
|
|
300
|
+
init(element: HTMLVideoElement, options?: ScrollVideoOptions): this;
|
|
301
|
+
replay(): this;
|
|
302
|
+
pause(): this;
|
|
303
|
+
resume(): this;
|
|
304
|
+
seek(p: number): this;
|
|
305
|
+
getProgress(): number;
|
|
306
|
+
destroy(): this;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Split text and stagger-animate each piece on scroll — Angular class-based API.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* @Component({ template: '<h2 #headline>Animate on scroll.</h2>' })
|
|
313
|
+
* export class HeroComponent implements AfterViewInit, OnDestroy {
|
|
314
|
+
* @ViewChild('headline') headlineRef!: ElementRef<HTMLElement>;
|
|
315
|
+
* private text = new ScrollTextRef();
|
|
316
|
+
*
|
|
317
|
+
* ngAfterViewInit() {
|
|
318
|
+
* this.text.init(this.headlineRef.nativeElement, {
|
|
319
|
+
* split: 'words',
|
|
320
|
+
* stagger: 0.05,
|
|
321
|
+
* from: { opacity: 0, y: 24 },
|
|
322
|
+
* once: true,
|
|
323
|
+
* });
|
|
324
|
+
* }
|
|
325
|
+
*
|
|
326
|
+
* ngOnDestroy() { this.text.destroy(); }
|
|
327
|
+
* }
|
|
328
|
+
*/
|
|
329
|
+
declare class ScrollTextRef {
|
|
330
|
+
private instance;
|
|
331
|
+
init(element: HTMLElement, options?: ScrollTextOptions): this;
|
|
332
|
+
replay(): this;
|
|
333
|
+
pause(): this;
|
|
334
|
+
resume(): this;
|
|
335
|
+
seek(p: number): this;
|
|
336
|
+
getProgress(): number;
|
|
152
337
|
destroy(): this;
|
|
153
338
|
}
|
|
154
339
|
|
|
155
|
-
export { type ScrollDrawInstance, type ScrollDrawOptions, ScrollDrawRef };
|
|
340
|
+
export { type ScrollAnimateOptions, ScrollAnimateRef, type ScrollCounterOptions, ScrollCounterRef, type ScrollDrawInstance, type ScrollDrawOptions, ScrollDrawRef, type ScrollTextOptions, ScrollTextRef, type ScrollVideoOptions, ScrollVideoRef };
|
package/dist/angular/index.d.ts
CHANGED
|
@@ -71,6 +71,14 @@ interface ScrollDrawOptions {
|
|
|
71
71
|
onProgress?: (alpha: number) => void;
|
|
72
72
|
onStart?: () => void;
|
|
73
73
|
onComplete?: () => void;
|
|
74
|
+
/** Fires when scroll position enters the trigger zone (scrolling forward). */
|
|
75
|
+
onEnter?: () => void;
|
|
76
|
+
/** Fires when scroll position exits the trigger zone at the end (scrolling forward). */
|
|
77
|
+
onLeave?: () => void;
|
|
78
|
+
/** Fires when scroll position re-enters the trigger zone from the end (scrolling back). */
|
|
79
|
+
onEnterBack?: () => void;
|
|
80
|
+
/** Fires when scroll position exits the trigger zone at the start (scrolling back). */
|
|
81
|
+
onLeaveBack?: () => void;
|
|
74
82
|
/**
|
|
75
83
|
* Trigger the animation when the element enters the viewport instead of
|
|
76
84
|
* tying it to scroll position. The draw runs over `duration` milliseconds,
|
|
@@ -119,14 +127,72 @@ interface ScrollDrawInstance {
|
|
|
119
127
|
getProgress: () => number;
|
|
120
128
|
}
|
|
121
129
|
|
|
130
|
+
interface ScrollAnimateOptions {
|
|
131
|
+
props: Record<string, string | number | [string | number, string | number]>;
|
|
132
|
+
trigger?: TriggerConfig;
|
|
133
|
+
easing?: EasingName | ((t: number) => number);
|
|
134
|
+
speed?: number;
|
|
135
|
+
once?: boolean;
|
|
136
|
+
axis?: 'x' | 'y';
|
|
137
|
+
scrollContainer?: string | Element;
|
|
138
|
+
native?: boolean;
|
|
139
|
+
onProgress?: (alpha: number) => void;
|
|
140
|
+
onComplete?: () => void;
|
|
141
|
+
/** Fires when scroll enters the trigger zone (scrolling forward). */
|
|
142
|
+
onEnter?: () => void;
|
|
143
|
+
/** Fires when scroll exits the trigger zone at the end (scrolling forward). */
|
|
144
|
+
onLeave?: () => void;
|
|
145
|
+
/** Fires when scroll re-enters the trigger zone from the end (scrolling back). */
|
|
146
|
+
onEnterBack?: () => void;
|
|
147
|
+
/** Fires when scroll exits the trigger zone at the start (scrolling back). */
|
|
148
|
+
onLeaveBack?: () => void;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
interface ScrollCounterOptions {
|
|
152
|
+
from?: number;
|
|
153
|
+
to: number;
|
|
154
|
+
format?: (value: number) => string;
|
|
155
|
+
easing?: EasingName | ((t: number) => number);
|
|
156
|
+
trigger?: TriggerConfig;
|
|
157
|
+
once?: boolean;
|
|
158
|
+
decimals?: number;
|
|
159
|
+
onComplete?: () => void;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
interface ScrollVideoOptions {
|
|
163
|
+
trigger?: TriggerConfig;
|
|
164
|
+
from?: number;
|
|
165
|
+
to?: number;
|
|
166
|
+
easing?: EasingName | ((t: number) => number);
|
|
167
|
+
once?: boolean;
|
|
168
|
+
axis?: 'x' | 'y';
|
|
169
|
+
preload?: 'auto' | 'metadata';
|
|
170
|
+
onReady?: () => void;
|
|
171
|
+
onComplete?: () => void;
|
|
172
|
+
onProgress?: (alpha: number) => void;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
interface ScrollTextOptions {
|
|
176
|
+
split?: 'chars' | 'words' | 'lines';
|
|
177
|
+
stagger?: number;
|
|
178
|
+
easing?: EasingName | ((t: number) => number);
|
|
179
|
+
from?: {
|
|
180
|
+
opacity?: number;
|
|
181
|
+
y?: number;
|
|
182
|
+
x?: number;
|
|
183
|
+
rotate?: number;
|
|
184
|
+
scale?: number;
|
|
185
|
+
};
|
|
186
|
+
trigger?: TriggerConfig;
|
|
187
|
+
once?: boolean;
|
|
188
|
+
onComplete?: () => void;
|
|
189
|
+
}
|
|
190
|
+
|
|
122
191
|
/**
|
|
123
192
|
* Framework-agnostic class for use in Angular components.
|
|
124
193
|
* No @angular/core dependency required.
|
|
125
194
|
*
|
|
126
195
|
* @example
|
|
127
|
-
* // In your Angular component:
|
|
128
|
-
* import { ScrollDrawRef } from 'svg-scroll-draw/angular';
|
|
129
|
-
*
|
|
130
196
|
* @Component({ template: '<div #container><svg>...</svg></div>' })
|
|
131
197
|
* export class HeroComponent implements AfterViewInit, OnDestroy {
|
|
132
198
|
* @ViewChild('container') containerRef!: ElementRef<HTMLElement>;
|
|
@@ -134,22 +200,141 @@ interface ScrollDrawInstance {
|
|
|
134
200
|
*
|
|
135
201
|
* ngAfterViewInit() {
|
|
136
202
|
* this.draw.init(this.containerRef.nativeElement, {
|
|
137
|
-
* easing: 'ease-out',
|
|
138
|
-
* speed: 1.2,
|
|
139
|
-
* fade: true,
|
|
203
|
+
* easing: 'ease-out', speed: 1.2, fade: true,
|
|
140
204
|
* });
|
|
141
205
|
* }
|
|
142
206
|
*
|
|
143
207
|
* ngOnDestroy() { this.draw.destroy(); }
|
|
144
|
-
*
|
|
145
|
-
* replay() { this.draw.replay(); }
|
|
146
208
|
* }
|
|
147
209
|
*/
|
|
148
210
|
declare class ScrollDrawRef {
|
|
149
211
|
private instance;
|
|
150
212
|
init(element: HTMLElement, options?: ScrollDrawOptions): this;
|
|
151
213
|
replay(): this;
|
|
214
|
+
pause(): this;
|
|
215
|
+
resume(): this;
|
|
216
|
+
seek(p: number): this;
|
|
217
|
+
getProgress(): number;
|
|
218
|
+
destroy(): this;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Animate any CSS property on any element driven by scroll — Angular class-based API.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* @Component({ template: '<div #el>...</div>' })
|
|
225
|
+
* export class CardComponent implements AfterViewInit, OnDestroy {
|
|
226
|
+
* @ViewChild('el') elRef!: ElementRef<HTMLElement>;
|
|
227
|
+
* private animate = new ScrollAnimateRef();
|
|
228
|
+
*
|
|
229
|
+
* ngAfterViewInit() {
|
|
230
|
+
* this.animate.init(this.elRef.nativeElement, {
|
|
231
|
+
* props: { opacity: [0, 1], transform: ['translateY(40px)', 'translateY(0)'] },
|
|
232
|
+
* easing: 'ease-out',
|
|
233
|
+
* once: true,
|
|
234
|
+
* });
|
|
235
|
+
* }
|
|
236
|
+
*
|
|
237
|
+
* ngOnDestroy() { this.animate.destroy(); }
|
|
238
|
+
* }
|
|
239
|
+
*/
|
|
240
|
+
declare class ScrollAnimateRef {
|
|
241
|
+
private instance;
|
|
242
|
+
init(element: HTMLElement, options: ScrollAnimateOptions): this;
|
|
243
|
+
replay(): this;
|
|
244
|
+
pause(): this;
|
|
245
|
+
resume(): this;
|
|
246
|
+
seek(p: number): this;
|
|
247
|
+
getProgress(): number;
|
|
248
|
+
destroy(): this;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Animate a number from `from` to `to` as the element scrolls into view — Angular class-based API.
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* @Component({ template: '<span #counter></span>' })
|
|
255
|
+
* export class StatsComponent implements AfterViewInit, OnDestroy {
|
|
256
|
+
* @ViewChild('counter') counterRef!: ElementRef<HTMLElement>;
|
|
257
|
+
* private counter = new ScrollCounterRef();
|
|
258
|
+
*
|
|
259
|
+
* ngAfterViewInit() {
|
|
260
|
+
* this.counter.init(this.counterRef.nativeElement, {
|
|
261
|
+
* to: 1_250_000,
|
|
262
|
+
* format: n => '$' + Math.round(n).toLocaleString(),
|
|
263
|
+
* once: true,
|
|
264
|
+
* });
|
|
265
|
+
* }
|
|
266
|
+
*
|
|
267
|
+
* ngOnDestroy() { this.counter.destroy(); }
|
|
268
|
+
* }
|
|
269
|
+
*/
|
|
270
|
+
declare class ScrollCounterRef {
|
|
271
|
+
private instance;
|
|
272
|
+
init(element: HTMLElement, options: ScrollCounterOptions): this;
|
|
273
|
+
replay(): this;
|
|
274
|
+
pause(): this;
|
|
275
|
+
resume(): this;
|
|
276
|
+
seek(p: number): this;
|
|
277
|
+
getProgress(): number;
|
|
278
|
+
destroy(): this;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Tie a <video> element's currentTime to scroll — Angular class-based API.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* @Component({ template: '<video #vid src="/hero.mp4" muted playsinline preload="auto"></video>' })
|
|
285
|
+
* export class HeroVideoComponent implements AfterViewInit, OnDestroy {
|
|
286
|
+
* @ViewChild('vid') vidRef!: ElementRef<HTMLVideoElement>;
|
|
287
|
+
* private video = new ScrollVideoRef();
|
|
288
|
+
*
|
|
289
|
+
* ngAfterViewInit() {
|
|
290
|
+
* this.video.init(this.vidRef.nativeElement, {
|
|
291
|
+
* trigger: { start: 'top top', end: 'bottom top' },
|
|
292
|
+
* });
|
|
293
|
+
* }
|
|
294
|
+
*
|
|
295
|
+
* ngOnDestroy() { this.video.destroy(); }
|
|
296
|
+
* }
|
|
297
|
+
*/
|
|
298
|
+
declare class ScrollVideoRef {
|
|
299
|
+
private instance;
|
|
300
|
+
init(element: HTMLVideoElement, options?: ScrollVideoOptions): this;
|
|
301
|
+
replay(): this;
|
|
302
|
+
pause(): this;
|
|
303
|
+
resume(): this;
|
|
304
|
+
seek(p: number): this;
|
|
305
|
+
getProgress(): number;
|
|
306
|
+
destroy(): this;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Split text and stagger-animate each piece on scroll — Angular class-based API.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* @Component({ template: '<h2 #headline>Animate on scroll.</h2>' })
|
|
313
|
+
* export class HeroComponent implements AfterViewInit, OnDestroy {
|
|
314
|
+
* @ViewChild('headline') headlineRef!: ElementRef<HTMLElement>;
|
|
315
|
+
* private text = new ScrollTextRef();
|
|
316
|
+
*
|
|
317
|
+
* ngAfterViewInit() {
|
|
318
|
+
* this.text.init(this.headlineRef.nativeElement, {
|
|
319
|
+
* split: 'words',
|
|
320
|
+
* stagger: 0.05,
|
|
321
|
+
* from: { opacity: 0, y: 24 },
|
|
322
|
+
* once: true,
|
|
323
|
+
* });
|
|
324
|
+
* }
|
|
325
|
+
*
|
|
326
|
+
* ngOnDestroy() { this.text.destroy(); }
|
|
327
|
+
* }
|
|
328
|
+
*/
|
|
329
|
+
declare class ScrollTextRef {
|
|
330
|
+
private instance;
|
|
331
|
+
init(element: HTMLElement, options?: ScrollTextOptions): this;
|
|
332
|
+
replay(): this;
|
|
333
|
+
pause(): this;
|
|
334
|
+
resume(): this;
|
|
335
|
+
seek(p: number): this;
|
|
336
|
+
getProgress(): number;
|
|
152
337
|
destroy(): this;
|
|
153
338
|
}
|
|
154
339
|
|
|
155
|
-
export { type ScrollDrawInstance, type ScrollDrawOptions, ScrollDrawRef };
|
|
340
|
+
export { type ScrollAnimateOptions, ScrollAnimateRef, type ScrollCounterOptions, ScrollCounterRef, type ScrollDrawInstance, type ScrollDrawOptions, ScrollDrawRef, type ScrollTextOptions, ScrollTextRef, type ScrollVideoOptions, ScrollVideoRef };
|