svg-scroll-draw 0.5.0 → 0.6.2

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.
Files changed (43) hide show
  1. package/README.md +5 -4
  2. package/dist/angular/index.cjs +3 -3
  3. package/dist/angular/index.d.mts +29 -1
  4. package/dist/angular/index.d.ts +29 -1
  5. package/dist/angular/index.mjs +3 -3
  6. package/dist/astro/index.cjs +3 -0
  7. package/dist/astro/index.d.mts +87 -0
  8. package/dist/astro/index.d.ts +87 -0
  9. package/dist/astro/index.mjs +3 -0
  10. package/dist/cdn/svg-scroll-draw.global.js +3 -3
  11. package/dist/group/index.cjs +3 -0
  12. package/dist/group/index.d.mts +97 -0
  13. package/dist/group/index.d.ts +97 -0
  14. package/dist/group/index.mjs +3 -0
  15. package/dist/index.cjs +3 -3
  16. package/dist/index.d.mts +29 -1
  17. package/dist/index.d.ts +29 -1
  18. package/dist/index.mjs +3 -3
  19. package/dist/nuxt/index.cjs +3 -0
  20. package/dist/nuxt/index.d.mts +174 -0
  21. package/dist/nuxt/index.d.ts +174 -0
  22. package/dist/nuxt/index.mjs +3 -0
  23. package/dist/react/index.cjs +3 -3
  24. package/dist/react/index.d.mts +49 -3
  25. package/dist/react/index.d.ts +49 -3
  26. package/dist/react/index.mjs +3 -3
  27. package/dist/solid/index.cjs +3 -3
  28. package/dist/solid/index.d.mts +29 -1
  29. package/dist/solid/index.d.ts +29 -1
  30. package/dist/solid/index.mjs +3 -3
  31. package/dist/svelte/index.cjs +3 -3
  32. package/dist/svelte/index.d.mts +29 -1
  33. package/dist/svelte/index.d.ts +29 -1
  34. package/dist/svelte/index.mjs +3 -3
  35. package/dist/vue/index.cjs +3 -3
  36. package/dist/vue/index.d.mts +21 -1
  37. package/dist/vue/index.d.ts +21 -1
  38. package/dist/vue/index.mjs +3 -3
  39. package/dist/web-component/index.cjs +3 -0
  40. package/dist/web-component/index.d.mts +2 -0
  41. package/dist/web-component/index.d.ts +2 -0
  42. package/dist/web-component/index.mjs +3 -0
  43. package/package.json +30 -4
package/README.md CHANGED
@@ -1,12 +1,13 @@
1
1
  # svg-scroll-draw
2
2
 
3
+ [![CI](https://github.com/DhruvilChauahan0210/ink-scroll/actions/workflows/ci.yml/badge.svg)](https://github.com/DhruvilChauahan0210/ink-scroll/actions/workflows/ci.yml)
3
4
  [![npm](https://img.shields.io/npm/v/svg-scroll-draw)](https://www.npmjs.com/package/svg-scroll-draw)
4
5
  [![downloads](https://img.shields.io/npm/dw/svg-scroll-draw)](https://www.npmjs.com/package/svg-scroll-draw)
5
6
  [![bundle size](https://img.shields.io/bundlephobia/minzip/svg-scroll-draw)](https://bundlephobia.com/package/svg-scroll-draw)
6
7
  [![license](https://img.shields.io/npm/l/svg-scroll-draw)](./LICENSE)
7
8
  [![GitHub stars](https://img.shields.io/github/stars/DhruvilChauahan0210/ink-scroll?style=flat)](https://github.com/DhruvilChauahan0210/ink-scroll/stargazers)
8
9
 
9
- > Scroll-driven SVG path animation. Zero dependencies. Under 3KB gzipped.
10
+ > Scroll-driven SVG path animation. Zero dependencies. ~3 KB gzipped.
10
11
 
11
12
  **[Live Demo](https://ink-scroll.vercel.app)** · [npm](https://www.npmjs.com/package/svg-scroll-draw) · [Report a bug](https://github.com/DhruvilChauahan0210/ink-scroll/issues)
12
13
 
@@ -58,7 +59,7 @@ const instance = scrollDraw('#my-svg-container', {
58
59
  instance.destroy();
59
60
  ```
60
61
 
61
- **[Try it on StackBlitz →](https://stackblitz.com/edit/svg-scroll-draw-vanilla)**
62
+ **[Try the Playground →](https://svg-scroll-draw.vercel.app/playground)**
62
63
 
63
64
  ### React / Next.js
64
65
 
@@ -78,7 +79,7 @@ export default function Hero() {
78
79
 
79
80
  > **Next.js App Router:** add `'use client'` to any component that uses `ScrollDraw`.
80
81
 
81
- **[Try it on StackBlitz →](https://stackblitz.com/edit/svg-scroll-draw-react)**
82
+ **[Try the Playground →](https://svg-scroll-draw.vercel.app/playground)**
82
83
 
83
84
  ### Vue 3
84
85
 
@@ -102,7 +103,7 @@ import { useScrollDraw } from 'svg-scroll-draw/vue';
102
103
  const containerRef = useScrollDraw({ easing: 'ease-out', speed: 1.2 });
103
104
  ```
104
105
 
105
- **[Try it on StackBlitz →](https://stackblitz.com/edit/svg-scroll-draw-vue)**
106
+ **[Try the Playground →](https://svg-scroll-draw.vercel.app/playground)**
106
107
 
107
108
  ### CDN / Web Component
108
109
 
@@ -1,3 +1,3 @@
1
- 'use strict';var X={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)};function _(e="top bottom"){let t=e.trim();if(/^\d+(\.\d+)?%$/.test(t))return {element:"top",viewport:t};let[n="top",o="bottom"]=t.split(/\s+/).filter(Boolean);return {element:n,viewport:o}}function te(e,t,n,o){switch(o){case "top":return e+n;case "center":return e+n+t/2;case "bottom":return e+n+t;default:return e+n}}function re(e,t){if(/^\d+(\.\d+)?%$/.test(e))return t*(parseFloat(e)/100);switch(e){case "top":return 0;case "center":return t/2;case "bottom":return t;default:return t}}function j(e){let t=e.tagName.toLowerCase();if(t==="rect"){let n=parseFloat(e.getAttribute("width")??"0"),o=parseFloat(e.getAttribute("height")??"0");return 2*(n+o)}if(t==="circle"){let n=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*n}return e.getTotalLength()}function ye(e,t,n){return Math.min(n,Math.max(t,e))}function z(e,t,n,o){return n===t?0:ye((e-t)/(n-t)*o,0,1)}function oe(e,t,n,o,i){let p=te(e.top,e.height,t,o.element)-re(o.viewport,n),d=te(e.top,e.height,t,i.element)-re(i.viewport,n);return {tStart:p,tEnd:d}}function ne(e){let t=/^#([a-f\d])([a-f\d])([a-f\d])$/i.exec(e);if(t)return [parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[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 o=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(e);return o?[parseInt(o[1]),parseInt(o[2]),parseInt(o[3])]:null}function se(e,t,n){let o=ne(e),i=ne(t);return !o||!i?e:`rgb(${Math.round(o[0]+(i[0]-o[0])*n)},${Math.round(o[1]+(i[1]-o[1])*n)},${Math.round(o[2]+(i[2]-o[2])*n)})`}function ie(e,t){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,t);}function be(e){let t=e.getAttribute("stroke"),n=e.getAttribute("fill");!t||t==="none"?ie("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&ie("Element has a fill \u2014 it may obscure the stroke animation.",e);}function ge(e,t,n){let o=document.createElement("div");o.setAttribute("data-svg-scroll-draw-debug",""),o.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 i(){let p=n==="x"?window.scrollX:window.scrollY,d=e-p,A=t-p,T=n==="x";o.innerHTML=`
2
- <div style="position:absolute;${T?`left:${d}px;top:0;bottom:0;border-left:2px dashed #22c55e;`:`top:${d}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;${T?`left:${A}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${A}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",i,{passive:true}),i(),o}function le(e,t={}){if(typeof window>"u")return {destroy:()=>{},replay:()=>{}};let n=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:o="path, polyline, line, polygon, rect, circle",speed:i=1,fade:p=false,easing:d="linear",trigger:A={},stagger:T=0,direction:b="forward",once:J=false,debug:ce=false,axis:f="y",scrollContainer:W,autoReverse:K=false,delay:Q=0,strokeColor:g,strokeWidth:w,waypoints:G,onProgress:ue,onStart:pe,onComplete:U}=t,Y=typeof d=="function"?d:X[d]??X.linear,fe=_(A.start??"top bottom"),de=_(A.end??"bottom top"),l=typeof W=="string"?document.querySelector(W):W??null,v=Array.isArray(g)?g[0]:null,x=Array.isArray(g)?g[1]:typeof g=="string"?g:null,m=Array.isArray(w)?w[0]:null,E=Array.isArray(w)?w[1]:typeof w=="number"?w:null,I=Array.from(e.querySelectorAll(o)),h=[],$=0,k=0,L=false,V=false,M=0,N=false,F=-1,C=-1,P=null,R=new Set;function q(){return l?f==="x"?l.scrollLeft:l.scrollTop:f==="x"?window.scrollX:window.scrollY}function me(){return l?f==="x"?l.clientWidth:l.clientHeight:f==="x"?window.innerWidth:window.innerHeight}function Z(){let r=e.getBoundingClientRect(),s,D,y;if(l){let c=l.getBoundingClientRect();s=f==="x"?r.left-c.left+l.scrollLeft:r.top-c.top+l.scrollTop,D=f==="x"?r.width:r.height,y=q();}else s=f==="x"?r.left:r.top,D=f==="x"?r.width:r.height,y=q();let a=oe({top:s,height:D},y,me(),fe,de);$=a.tStart,k=a.tEnd,ce&&process.env.NODE_ENV!=="production"&&(P?.remove(),P=ge($,k,f));}function he(){I.forEach((r,s)=>{r.style.strokeDasharray=`${h[s]}`,r.style.strokeDashoffset=b==="reverse"?"0":`${h[s]}`,p?r.style.opacity=b==="reverse"?"1":"0":r.style.opacity="",v&&(r.style.stroke=v),m!==null&&(r.style.strokeWidth=`${m}`);});}if(I.forEach(r=>{be(r);let s=j(r);h.push(s),n?(r.style.strokeDasharray=`${s}`,r.style.strokeDashoffset=b==="reverse"?`${s}`:"0",p&&(r.style.opacity="1"),x&&(r.style.stroke=x),E!==null&&(r.style.strokeWidth=`${E}`)):(r.style.strokeDasharray=`${s}`,r.style.strokeDashoffset=b==="reverse"?"0":`${s}`,p?r.style.opacity=b==="reverse"?"1":"0":r.style.opacity="",v&&(r.style.stroke=v),m!==null&&(r.style.strokeWidth=`${m}`));}),n)return U?.(),{destroy:()=>{},replay:()=>{}};Z();function ee(){if(!N)return;let r=q(),s=K?C===-1||r>=C?"forward":"reverse":b;C=r;let D=k-$,y=true;if(I.forEach((a,c)=>{let S=c*T*D,u=Y(z(r,$+S,k+S,i));J&&!K&&(F=Math.max(F,u),u=F),a.style.strokeDashoffset=s==="reverse"?`${h[c]*u}`:`${h[c]*(1-u)}`,p&&(a.style.opacity=s==="reverse"?`${1-u}`:`${u}`),v&&x?a.style.stroke=se(v,x,u):x&&(a.style.stroke=x),m!==null&&E!==null?a.style.strokeWidth=`${m+(E-m)*u}`:E!==null&&(a.style.strokeWidth=`${E}`),c===0&&ue?.(u),u<1&&(y=false);}),G){let a=Y(z(r,$,k,i));for(let c in G){let S=parseFloat(c);a>=S&&!R.has(S)&&(R.add(S),G[c]?.());}}!V&&z(r,$,k,i)>0&&(V=true,pe?.()),y&&!L?(L=true,U?.()):!y&&!J&&(L=false),M=requestAnimationFrame(ee);}let B=new IntersectionObserver(r=>{r.forEach(s=>{N=s.isIntersecting,N?M=requestAnimationFrame(ee):cancelAnimationFrame(M);});},{root:l??null}),H;function O(){clearTimeout(H),H=setTimeout(()=>{I.forEach((r,s)=>{h[s]=j(r),r.style.strokeDasharray=`${h[s]}`;}),Z();},150);}return window.addEventListener("resize",O),window.addEventListener("orientationchange",O),Q>0?setTimeout(()=>B.observe(e),Q):B.observe(e),{destroy(){cancelAnimationFrame(M),B.disconnect(),window.removeEventListener("resize",O),window.removeEventListener("orientationchange",O),clearTimeout(H),P?.remove();},replay(){F=-1,C=-1,V=false,L=false,R.clear(),he();}}}var ae=class{constructor(){this.instance=null;}init(t,n={}){return this.destroy(),this.instance=le(t,n),this}replay(){return this.instance?.replay(),this}destroy(){return this.instance?.destroy(),this.instance=null,this}};exports.ScrollDrawRef=ae;
1
+ 'use strict';var me={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)};function de(e="top bottom"){let r=e.trim();if(/^\d+(\.\d+)?%$/.test(r))return {element:"top",viewport:r};let[s="top",o="bottom"]=r.split(/\s+/).filter(Boolean);return {element:s,viewport:o}}function Ae(e,r,s,o){switch(o){case "top":return e+s;case "center":return e+s+r/2;case "bottom":return e+s+r;default:return e+s}}function ke(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 ye(e){let r=e.tagName.toLowerCase();if(r==="rect"){let s=parseFloat(e.getAttribute("width")??"0"),o=parseFloat(e.getAttribute("height")??"0");return 2*(s+o)}if(r==="circle"){let s=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*s}return e.getTotalLength()}function Ve(e,r,s){return Math.min(s,Math.max(r,e))}function G(e,r,s,o){return s===r?0:Ve((e-r)/(s-r)*o,0,1)}function Se(e,r,s,o,a){let f=Ae(e.top,e.height,r,o.element)-ke(o.viewport,s),p=Ae(e.top,e.height,r,a.element)-ke(a.viewport,s);return {tStart:f,tEnd:p}}function Te(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 s=/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(s)return [parseInt(s[1],16),parseInt(s[2],16),parseInt(s[3],16)];let o=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(e);return o?[parseInt(o[1]),parseInt(o[2]),parseInt(o[3])]:null}function he(e,r,s){let o=Te(e),a=Te(r);return !o||!a?e:`rgb(${Math.round(o[0]+(a[0]-o[0])*s)},${Math.round(o[1]+(a[1]-o[1])*s)},${Math.round(o[2]+(a[2]-o[2])*s)})`}function Me(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}function ze(e){let r=e.getAttribute("stroke"),s=e.getAttribute("fill");!r||r==="none"?Me("Element has no stroke \u2014 path will not be visible.",e):s&&s!=="none"&&s!=="transparent"&&Me("Element has a fill \u2014 it may obscure the stroke animation.",e);}function Ge(e,r,s){let o=document.createElement("div");o.setAttribute("data-svg-scroll-draw-debug",""),o.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 a(){let f=s==="x"?window.scrollX:window.scrollY,p=e-f,L=r-f,B=s==="x";o.innerHTML=`
2
+ <div style="position:absolute;${B?`left:${p}px;top:0;bottom:0;border-left:2px dashed #22c55e;`:`top:${p}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;${B?`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(o),window.addEventListener("scroll",a,{passive:true}),a(),o}function De(e,r,s){let o=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),a=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,f=>{let p=parseFloat(f),L=o[a++]??p;return String(+(p+(L-p)*s).toFixed(4))})}function Le(e,r={}){if(typeof window>"u")return {destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};let s=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:o="path, polyline, line, polygon, rect, circle",speed:a=1,fade:f=false,easing:p="linear",trigger:L={},stagger:B=0,direction:I="forward",once:X=false,debug:Oe=false,axis:x="y",scrollContainer:ne,autoReverse:se=false,delay:ge=0,strokeColor:C,strokeWidth:N,fillOpacity:R,waypoints:oe,velocityScale:ie=false,threshold:Fe=0,rootMargin:Pe="0px",repeat:_=0,repeatDelay:be=0,morphTo:O,clip:le,onProgress:we,onStart:ve,onComplete:j}=r,W=le===true?"left":typeof le=="string"?le:false,ae=typeof p=="function"?p:me[p]??me.linear,Ce=de(L.start??"top bottom"),Ne=de(L.end??"bottom top"),d=typeof ne=="string"?document.querySelector(ne):ne??null,A=Array.isArray(C)?C[0]:null,y=Array.isArray(C)?C[1]:typeof C=="string"?C:null,h=Array.isArray(N)?N[0]:null,g=Array.isArray(N)?N[1]:typeof N=="number"?N:null,b=Array.isArray(R)?R[0]:null,w=Array.isArray(R)?R[1]:typeof R=="number"?R:null;function V(t){let n=t*100;switch(W){case "right":return `inset(0 0 0 ${100-n}%)`;case "top":return `inset(0 0 ${100-n}% 0)`;case "bottom":return `inset(${100-n}% 0 0 0)`;case "center":return `circle(${t*150}% at 50% 50%)`;default:return `inset(0 ${100-n}% 0 0)`}}let H=W?[]:Array.from(e.querySelectorAll(o)),$=[],k=[],T=0,S=0,E=false,F=false,M=0,J=false,v=-1,K=-1,P=false,Q=0,q=0,U,ce=null,Y=new Set,Z=-1,xe=performance.now();function ue(){return d?x==="x"?d.scrollLeft:d.scrollTop:x==="x"?window.scrollX:window.scrollY}function Re(){return d?x==="x"?d.clientWidth:d.clientHeight:x==="x"?window.innerWidth:window.innerHeight}function $e(){let t=e.getBoundingClientRect(),n,l,m;if(d){let z=d.getBoundingClientRect();n=x==="x"?t.left-z.left+d.scrollLeft:t.top-z.top+d.scrollTop,l=x==="x"?t.width:t.height,m=ue();}else n=x==="x"?t.left:t.top,l=x==="x"?t.width:t.height,m=ue();let re=Se({top:n,height:l},m,Re(),Ce,Ne);T=re.tStart,S=re.tEnd,Oe&&process.env.NODE_ENV!=="production"&&(ce?.remove(),ce=Ge(T,S,x));}function We(t,n){if(W){let l=n==="reverse"?1-t:t;e.style.clipPath=V(l);return}H.forEach((l,m)=>{l.style.strokeDashoffset=n==="reverse"?`${$[m]*t}`:`${$[m]*(1-t)}`,f&&(l.style.opacity=n==="reverse"?`${1-t}`:`${t}`),A&&y?l.style.stroke=he(A,y,t):y&&(l.style.stroke=y),h!==null&&g!==null?l.style.strokeWidth=`${h+(g-h)*t}`:g!==null&&(l.style.strokeWidth=`${g}`),b!==null&&w!==null?l.style.fillOpacity=`${b+(w-b)*t}`:w!==null&&(l.style.fillOpacity=`${w}`),O&&l.tagName.toLowerCase()==="path"&&k[m]&&l.setAttribute("d",De(k[m],O,t));});}function Ee(){if(W){e.style.clipPath=V(0);return}H.forEach((t,n)=>{t.style.strokeDasharray=`${$[n]}`,t.style.strokeDashoffset=I==="reverse"?"0":`${$[n]}`,f?t.style.opacity=I==="reverse"?"1":"0":t.style.opacity="",A&&(t.style.stroke=A),h!==null&&(t.style.strokeWidth=`${h}`),b!==null&&(t.style.fillOpacity=`${b}`),O&&t.tagName.toLowerCase()==="path"&&k[n]&&t.setAttribute("d",k[n]);});}if(H.forEach(t=>{ze(t);let n=ye(t);$.push(n),t.tagName.toLowerCase()==="path"?k.push(t.getAttribute("d")??""):k.push(""),s?(t.style.strokeDasharray=`${n}`,t.style.strokeDashoffset=I==="reverse"?`${n}`:"0",f&&(t.style.opacity="1"),y&&(t.style.stroke=y),g!==null&&(t.style.strokeWidth=`${g}`),w!==null&&(t.style.fillOpacity=`${w}`),O&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",O)):(t.style.strokeDasharray=`${n}`,t.style.strokeDashoffset=I==="reverse"?"0":`${n}`,f?t.style.opacity=I==="reverse"?"1":"0":t.style.opacity="",A&&(t.style.stroke=A),h!==null&&(t.style.strokeWidth=`${h}`),b!==null&&(t.style.fillOpacity=`${b}`));}),W){if(s)return e.style.clipPath=V(1),j?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};e.style.clipPath=V(0);}else if(s)return j?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};$e();function ee(){if(!J||P)return;let t=performance.now(),n=ue(),l=a;if(ie!==false){let i=t-xe,c=i>0?Math.abs(n-(Z<0?n:Z))/i:0;l=a*Math.max(.2,1+c*(typeof ie=="number"?ie:1)*.04);}Z=n,xe=t;let m=se?K===-1||n>=K?"forward":"reverse":I;K=n;let re=S-T,z=true;if(W){let i=ae(G(n,T,S,l));X&&!se&&(v=Math.max(v,i),i=v),Q=i;let c=m==="reverse"?1-i:i;e.style.clipPath=V(c),we?.(i),!F&&G(n,T,S,l)>0&&(F=true,ve?.()),i>=1&&!E?(E=true,j?.(),q<(_==="infinite"?1/0:_??0)&&(q++,U=setTimeout(()=>{v=-1,F=false,E=false,e.style.clipPath=V(0);},be))):i<1&&!X&&(E=false),M=requestAnimationFrame(ee);return}if(H.forEach((i,c)=>{let D=c*B*re,u=ae(G(n,T+D,S+D,l));X&&!se&&(v=Math.max(v,u),u=v),Q=u,i.style.strokeDashoffset=m==="reverse"?`${$[c]*u}`:`${$[c]*(1-u)}`,f&&(i.style.opacity=m==="reverse"?`${1-u}`:`${u}`),A&&y?i.style.stroke=he(A,y,u):y&&(i.style.stroke=y),h!==null&&g!==null?i.style.strokeWidth=`${h+(g-h)*u}`:g!==null&&(i.style.strokeWidth=`${g}`),b!==null&&w!==null?i.style.fillOpacity=`${b+(w-b)*u}`:w!==null&&(i.style.fillOpacity=`${w}`),O&&i.tagName.toLowerCase()==="path"&&k[c]&&i.setAttribute("d",De(k[c],O,u)),c===0&&we?.(u),u<1&&(z=false);}),oe){let i=ae(G(n,T,S,l));for(let c in oe){let D=parseFloat(c);i>=D&&!Y.has(D)&&(Y.add(D),oe[c]?.());}}!F&&G(n,T,S,l)>0&&(F=true,ve?.()),z&&!E?(E=true,j?.(),q<(_==="infinite"?1/0:_??0)&&(q++,U=setTimeout(()=>{v=-1,F=false,E=false,Y.clear(),Ee();},be))):!z&&!X&&(E=false),M=requestAnimationFrame(ee);}let fe=new IntersectionObserver(t=>{t.forEach(n=>{J=n.isIntersecting,J&&!P?M=requestAnimationFrame(ee):cancelAnimationFrame(M);});},{root:d??null,threshold:Fe,rootMargin:Pe}),pe;function te(){clearTimeout(pe),pe=setTimeout(()=>{H.forEach((t,n)=>{$[n]=ye(t),t.style.strokeDasharray=`${$[n]}`;}),$e();},150);}return window.addEventListener("resize",te),window.addEventListener("orientationchange",te),ge>0?setTimeout(()=>fe.observe(e),ge):fe.observe(e),{destroy(){cancelAnimationFrame(M),clearTimeout(U),fe.disconnect(),window.removeEventListener("resize",te),window.removeEventListener("orientationchange",te),clearTimeout(pe),ce?.remove();},replay(){v=-1,K=-1,Z=-1,F=false,E=false,q=0,P=false,Y.clear(),clearTimeout(U),Ee();},pause(){P=true,cancelAnimationFrame(M);},resume(){P&&(P=false,J&&(M=requestAnimationFrame(ee)));},seek(t){let n=Math.min(1,Math.max(0,t));Q=n,v=n,P=true,cancelAnimationFrame(M),We(n,I);},getProgress(){return Q}}}var Ie=class{constructor(){this.instance=null;}init(r,s={}){return this.destroy(),this.instance=Le(r,s),this}replay(){return this.instance?.replay(),this}destroy(){return this.instance?.destroy(),this.instance=null,this}};exports.ScrollDrawRef=Ie;
@@ -19,14 +19,34 @@ interface ScrollDrawOptions {
19
19
  scrollContainer?: string | Element;
20
20
  /** Automatically reverse the animation when the user scrolls back up. */
21
21
  autoReverse?: boolean;
22
- /** Delay in milliseconds before the engine starts observing (useful for page-load sequences). */
22
+ /** Delay in milliseconds before the engine starts observing. */
23
23
  delay?: number;
24
24
  /** Animate stroke color. Single string = static override. Tuple = interpolate from → to. */
25
25
  strokeColor?: string | [string, string];
26
26
  /** Animate stroke width. Single number = static override. Tuple = interpolate from → to. */
27
27
  strokeWidth?: number | [number, number];
28
+ /** Animate fill opacity. Single number = static override. Tuple [from, to] = interpolate as the path draws. Use [0, 1] to flood fill in sync with the stroke draw. */
29
+ fillOpacity?: number | [number, number];
30
+ /**
31
+ * Reveal the container using CSS clip-path instead of stroke-dashoffset.
32
+ * Works on any content — SVG, images, text, divs.
33
+ * `true` defaults to `'left'`. Values: `'left' | 'right' | 'top' | 'bottom' | 'center'`.
34
+ */
35
+ clip?: boolean | 'left' | 'right' | 'top' | 'bottom' | 'center';
28
36
  /** Fire callbacks at specific progress thresholds (0–1). Resets on replay(). */
29
37
  waypoints?: Record<number, () => void>;
38
+ /** Scale animation speed by scroll velocity — faster scrolling = faster draw. Pass a number to control sensitivity (default 1). */
39
+ velocityScale?: boolean | number;
40
+ /** IntersectionObserver threshold (0–1). Default 0. */
41
+ threshold?: number;
42
+ /** IntersectionObserver rootMargin. Default "0px". */
43
+ rootMargin?: string;
44
+ /** Repeat the animation N times after completion. Use 'infinite' to loop forever. */
45
+ repeat?: number | 'infinite';
46
+ /** Milliseconds to wait between repeats. Default 0. */
47
+ repeatDelay?: number;
48
+ /** Target path `d` attribute to morph toward as the animation progresses. Paths must have compatible structures. */
49
+ morphTo?: string;
30
50
  onProgress?: (alpha: number) => void;
31
51
  onStart?: () => void;
32
52
  onComplete?: () => void;
@@ -35,6 +55,14 @@ interface ScrollDrawInstance {
35
55
  destroy: () => void;
36
56
  /** Reset and replay the animation from the beginning. */
37
57
  replay: () => void;
58
+ /** Pause the animation at the current progress. */
59
+ pause: () => void;
60
+ /** Resume a paused animation. */
61
+ resume: () => void;
62
+ /** Jump to a specific progress value (0–1) and pause. */
63
+ seek: (progress: number) => void;
64
+ /** Returns current draw progress (0–1). */
65
+ getProgress: () => number;
38
66
  }
39
67
 
40
68
  /**
@@ -19,14 +19,34 @@ interface ScrollDrawOptions {
19
19
  scrollContainer?: string | Element;
20
20
  /** Automatically reverse the animation when the user scrolls back up. */
21
21
  autoReverse?: boolean;
22
- /** Delay in milliseconds before the engine starts observing (useful for page-load sequences). */
22
+ /** Delay in milliseconds before the engine starts observing. */
23
23
  delay?: number;
24
24
  /** Animate stroke color. Single string = static override. Tuple = interpolate from → to. */
25
25
  strokeColor?: string | [string, string];
26
26
  /** Animate stroke width. Single number = static override. Tuple = interpolate from → to. */
27
27
  strokeWidth?: number | [number, number];
28
+ /** Animate fill opacity. Single number = static override. Tuple [from, to] = interpolate as the path draws. Use [0, 1] to flood fill in sync with the stroke draw. */
29
+ fillOpacity?: number | [number, number];
30
+ /**
31
+ * Reveal the container using CSS clip-path instead of stroke-dashoffset.
32
+ * Works on any content — SVG, images, text, divs.
33
+ * `true` defaults to `'left'`. Values: `'left' | 'right' | 'top' | 'bottom' | 'center'`.
34
+ */
35
+ clip?: boolean | 'left' | 'right' | 'top' | 'bottom' | 'center';
28
36
  /** Fire callbacks at specific progress thresholds (0–1). Resets on replay(). */
29
37
  waypoints?: Record<number, () => void>;
38
+ /** Scale animation speed by scroll velocity — faster scrolling = faster draw. Pass a number to control sensitivity (default 1). */
39
+ velocityScale?: boolean | number;
40
+ /** IntersectionObserver threshold (0–1). Default 0. */
41
+ threshold?: number;
42
+ /** IntersectionObserver rootMargin. Default "0px". */
43
+ rootMargin?: string;
44
+ /** Repeat the animation N times after completion. Use 'infinite' to loop forever. */
45
+ repeat?: number | 'infinite';
46
+ /** Milliseconds to wait between repeats. Default 0. */
47
+ repeatDelay?: number;
48
+ /** Target path `d` attribute to morph toward as the animation progresses. Paths must have compatible structures. */
49
+ morphTo?: string;
30
50
  onProgress?: (alpha: number) => void;
31
51
  onStart?: () => void;
32
52
  onComplete?: () => void;
@@ -35,6 +55,14 @@ interface ScrollDrawInstance {
35
55
  destroy: () => void;
36
56
  /** Reset and replay the animation from the beginning. */
37
57
  replay: () => void;
58
+ /** Pause the animation at the current progress. */
59
+ pause: () => void;
60
+ /** Resume a paused animation. */
61
+ resume: () => void;
62
+ /** Jump to a specific progress value (0–1) and pause. */
63
+ seek: (progress: number) => void;
64
+ /** Returns current draw progress (0–1). */
65
+ getProgress: () => number;
38
66
  }
39
67
 
40
68
  /**
@@ -1,3 +1,3 @@
1
- var X={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)};function _(e="top bottom"){let t=e.trim();if(/^\d+(\.\d+)?%$/.test(t))return {element:"top",viewport:t};let[n="top",o="bottom"]=t.split(/\s+/).filter(Boolean);return {element:n,viewport:o}}function te(e,t,n,o){switch(o){case "top":return e+n;case "center":return e+n+t/2;case "bottom":return e+n+t;default:return e+n}}function re(e,t){if(/^\d+(\.\d+)?%$/.test(e))return t*(parseFloat(e)/100);switch(e){case "top":return 0;case "center":return t/2;case "bottom":return t;default:return t}}function j(e){let t=e.tagName.toLowerCase();if(t==="rect"){let n=parseFloat(e.getAttribute("width")??"0"),o=parseFloat(e.getAttribute("height")??"0");return 2*(n+o)}if(t==="circle"){let n=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*n}return e.getTotalLength()}function ye(e,t,n){return Math.min(n,Math.max(t,e))}function z(e,t,n,o){return n===t?0:ye((e-t)/(n-t)*o,0,1)}function oe(e,t,n,o,i){let p=te(e.top,e.height,t,o.element)-re(o.viewport,n),d=te(e.top,e.height,t,i.element)-re(i.viewport,n);return {tStart:p,tEnd:d}}function ne(e){let t=/^#([a-f\d])([a-f\d])([a-f\d])$/i.exec(e);if(t)return [parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[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 o=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(e);return o?[parseInt(o[1]),parseInt(o[2]),parseInt(o[3])]:null}function se(e,t,n){let o=ne(e),i=ne(t);return !o||!i?e:`rgb(${Math.round(o[0]+(i[0]-o[0])*n)},${Math.round(o[1]+(i[1]-o[1])*n)},${Math.round(o[2]+(i[2]-o[2])*n)})`}function ie(e,t){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,t);}function be(e){let t=e.getAttribute("stroke"),n=e.getAttribute("fill");!t||t==="none"?ie("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&ie("Element has a fill \u2014 it may obscure the stroke animation.",e);}function ge(e,t,n){let o=document.createElement("div");o.setAttribute("data-svg-scroll-draw-debug",""),o.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 i(){let p=n==="x"?window.scrollX:window.scrollY,d=e-p,A=t-p,T=n==="x";o.innerHTML=`
2
- <div style="position:absolute;${T?`left:${d}px;top:0;bottom:0;border-left:2px dashed #22c55e;`:`top:${d}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;${T?`left:${A}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${A}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",i,{passive:true}),i(),o}function le(e,t={}){if(typeof window>"u")return {destroy:()=>{},replay:()=>{}};let n=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:o="path, polyline, line, polygon, rect, circle",speed:i=1,fade:p=false,easing:d="linear",trigger:A={},stagger:T=0,direction:b="forward",once:J=false,debug:ce=false,axis:f="y",scrollContainer:W,autoReverse:K=false,delay:Q=0,strokeColor:g,strokeWidth:w,waypoints:G,onProgress:ue,onStart:pe,onComplete:U}=t,Y=typeof d=="function"?d:X[d]??X.linear,fe=_(A.start??"top bottom"),de=_(A.end??"bottom top"),l=typeof W=="string"?document.querySelector(W):W??null,v=Array.isArray(g)?g[0]:null,x=Array.isArray(g)?g[1]:typeof g=="string"?g:null,m=Array.isArray(w)?w[0]:null,E=Array.isArray(w)?w[1]:typeof w=="number"?w:null,I=Array.from(e.querySelectorAll(o)),h=[],$=0,k=0,L=false,V=false,M=0,N=false,F=-1,C=-1,P=null,R=new Set;function q(){return l?f==="x"?l.scrollLeft:l.scrollTop:f==="x"?window.scrollX:window.scrollY}function me(){return l?f==="x"?l.clientWidth:l.clientHeight:f==="x"?window.innerWidth:window.innerHeight}function Z(){let r=e.getBoundingClientRect(),s,D,y;if(l){let c=l.getBoundingClientRect();s=f==="x"?r.left-c.left+l.scrollLeft:r.top-c.top+l.scrollTop,D=f==="x"?r.width:r.height,y=q();}else s=f==="x"?r.left:r.top,D=f==="x"?r.width:r.height,y=q();let a=oe({top:s,height:D},y,me(),fe,de);$=a.tStart,k=a.tEnd,ce&&process.env.NODE_ENV!=="production"&&(P?.remove(),P=ge($,k,f));}function he(){I.forEach((r,s)=>{r.style.strokeDasharray=`${h[s]}`,r.style.strokeDashoffset=b==="reverse"?"0":`${h[s]}`,p?r.style.opacity=b==="reverse"?"1":"0":r.style.opacity="",v&&(r.style.stroke=v),m!==null&&(r.style.strokeWidth=`${m}`);});}if(I.forEach(r=>{be(r);let s=j(r);h.push(s),n?(r.style.strokeDasharray=`${s}`,r.style.strokeDashoffset=b==="reverse"?`${s}`:"0",p&&(r.style.opacity="1"),x&&(r.style.stroke=x),E!==null&&(r.style.strokeWidth=`${E}`)):(r.style.strokeDasharray=`${s}`,r.style.strokeDashoffset=b==="reverse"?"0":`${s}`,p?r.style.opacity=b==="reverse"?"1":"0":r.style.opacity="",v&&(r.style.stroke=v),m!==null&&(r.style.strokeWidth=`${m}`));}),n)return U?.(),{destroy:()=>{},replay:()=>{}};Z();function ee(){if(!N)return;let r=q(),s=K?C===-1||r>=C?"forward":"reverse":b;C=r;let D=k-$,y=true;if(I.forEach((a,c)=>{let S=c*T*D,u=Y(z(r,$+S,k+S,i));J&&!K&&(F=Math.max(F,u),u=F),a.style.strokeDashoffset=s==="reverse"?`${h[c]*u}`:`${h[c]*(1-u)}`,p&&(a.style.opacity=s==="reverse"?`${1-u}`:`${u}`),v&&x?a.style.stroke=se(v,x,u):x&&(a.style.stroke=x),m!==null&&E!==null?a.style.strokeWidth=`${m+(E-m)*u}`:E!==null&&(a.style.strokeWidth=`${E}`),c===0&&ue?.(u),u<1&&(y=false);}),G){let a=Y(z(r,$,k,i));for(let c in G){let S=parseFloat(c);a>=S&&!R.has(S)&&(R.add(S),G[c]?.());}}!V&&z(r,$,k,i)>0&&(V=true,pe?.()),y&&!L?(L=true,U?.()):!y&&!J&&(L=false),M=requestAnimationFrame(ee);}let B=new IntersectionObserver(r=>{r.forEach(s=>{N=s.isIntersecting,N?M=requestAnimationFrame(ee):cancelAnimationFrame(M);});},{root:l??null}),H;function O(){clearTimeout(H),H=setTimeout(()=>{I.forEach((r,s)=>{h[s]=j(r),r.style.strokeDasharray=`${h[s]}`;}),Z();},150);}return window.addEventListener("resize",O),window.addEventListener("orientationchange",O),Q>0?setTimeout(()=>B.observe(e),Q):B.observe(e),{destroy(){cancelAnimationFrame(M),B.disconnect(),window.removeEventListener("resize",O),window.removeEventListener("orientationchange",O),clearTimeout(H),P?.remove();},replay(){F=-1,C=-1,V=false,L=false,R.clear(),he();}}}var ae=class{constructor(){this.instance=null;}init(t,n={}){return this.destroy(),this.instance=le(t,n),this}replay(){return this.instance?.replay(),this}destroy(){return this.instance?.destroy(),this.instance=null,this}};export{ae as ScrollDrawRef};
1
+ var me={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)};function de(e="top bottom"){let r=e.trim();if(/^\d+(\.\d+)?%$/.test(r))return {element:"top",viewport:r};let[s="top",o="bottom"]=r.split(/\s+/).filter(Boolean);return {element:s,viewport:o}}function Ae(e,r,s,o){switch(o){case "top":return e+s;case "center":return e+s+r/2;case "bottom":return e+s+r;default:return e+s}}function ke(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 ye(e){let r=e.tagName.toLowerCase();if(r==="rect"){let s=parseFloat(e.getAttribute("width")??"0"),o=parseFloat(e.getAttribute("height")??"0");return 2*(s+o)}if(r==="circle"){let s=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*s}return e.getTotalLength()}function Ve(e,r,s){return Math.min(s,Math.max(r,e))}function G(e,r,s,o){return s===r?0:Ve((e-r)/(s-r)*o,0,1)}function Se(e,r,s,o,a){let f=Ae(e.top,e.height,r,o.element)-ke(o.viewport,s),p=Ae(e.top,e.height,r,a.element)-ke(a.viewport,s);return {tStart:f,tEnd:p}}function Te(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 s=/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(s)return [parseInt(s[1],16),parseInt(s[2],16),parseInt(s[3],16)];let o=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(e);return o?[parseInt(o[1]),parseInt(o[2]),parseInt(o[3])]:null}function he(e,r,s){let o=Te(e),a=Te(r);return !o||!a?e:`rgb(${Math.round(o[0]+(a[0]-o[0])*s)},${Math.round(o[1]+(a[1]-o[1])*s)},${Math.round(o[2]+(a[2]-o[2])*s)})`}function Me(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}function ze(e){let r=e.getAttribute("stroke"),s=e.getAttribute("fill");!r||r==="none"?Me("Element has no stroke \u2014 path will not be visible.",e):s&&s!=="none"&&s!=="transparent"&&Me("Element has a fill \u2014 it may obscure the stroke animation.",e);}function Ge(e,r,s){let o=document.createElement("div");o.setAttribute("data-svg-scroll-draw-debug",""),o.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 a(){let f=s==="x"?window.scrollX:window.scrollY,p=e-f,L=r-f,B=s==="x";o.innerHTML=`
2
+ <div style="position:absolute;${B?`left:${p}px;top:0;bottom:0;border-left:2px dashed #22c55e;`:`top:${p}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;${B?`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(o),window.addEventListener("scroll",a,{passive:true}),a(),o}function De(e,r,s){let o=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),a=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,f=>{let p=parseFloat(f),L=o[a++]??p;return String(+(p+(L-p)*s).toFixed(4))})}function Le(e,r={}){if(typeof window>"u")return {destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};let s=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:o="path, polyline, line, polygon, rect, circle",speed:a=1,fade:f=false,easing:p="linear",trigger:L={},stagger:B=0,direction:I="forward",once:X=false,debug:Oe=false,axis:x="y",scrollContainer:ne,autoReverse:se=false,delay:ge=0,strokeColor:C,strokeWidth:N,fillOpacity:R,waypoints:oe,velocityScale:ie=false,threshold:Fe=0,rootMargin:Pe="0px",repeat:_=0,repeatDelay:be=0,morphTo:O,clip:le,onProgress:we,onStart:ve,onComplete:j}=r,W=le===true?"left":typeof le=="string"?le:false,ae=typeof p=="function"?p:me[p]??me.linear,Ce=de(L.start??"top bottom"),Ne=de(L.end??"bottom top"),d=typeof ne=="string"?document.querySelector(ne):ne??null,A=Array.isArray(C)?C[0]:null,y=Array.isArray(C)?C[1]:typeof C=="string"?C:null,h=Array.isArray(N)?N[0]:null,g=Array.isArray(N)?N[1]:typeof N=="number"?N:null,b=Array.isArray(R)?R[0]:null,w=Array.isArray(R)?R[1]:typeof R=="number"?R:null;function V(t){let n=t*100;switch(W){case "right":return `inset(0 0 0 ${100-n}%)`;case "top":return `inset(0 0 ${100-n}% 0)`;case "bottom":return `inset(${100-n}% 0 0 0)`;case "center":return `circle(${t*150}% at 50% 50%)`;default:return `inset(0 ${100-n}% 0 0)`}}let H=W?[]:Array.from(e.querySelectorAll(o)),$=[],k=[],T=0,S=0,E=false,F=false,M=0,J=false,v=-1,K=-1,P=false,Q=0,q=0,U,ce=null,Y=new Set,Z=-1,xe=performance.now();function ue(){return d?x==="x"?d.scrollLeft:d.scrollTop:x==="x"?window.scrollX:window.scrollY}function Re(){return d?x==="x"?d.clientWidth:d.clientHeight:x==="x"?window.innerWidth:window.innerHeight}function $e(){let t=e.getBoundingClientRect(),n,l,m;if(d){let z=d.getBoundingClientRect();n=x==="x"?t.left-z.left+d.scrollLeft:t.top-z.top+d.scrollTop,l=x==="x"?t.width:t.height,m=ue();}else n=x==="x"?t.left:t.top,l=x==="x"?t.width:t.height,m=ue();let re=Se({top:n,height:l},m,Re(),Ce,Ne);T=re.tStart,S=re.tEnd,Oe&&process.env.NODE_ENV!=="production"&&(ce?.remove(),ce=Ge(T,S,x));}function We(t,n){if(W){let l=n==="reverse"?1-t:t;e.style.clipPath=V(l);return}H.forEach((l,m)=>{l.style.strokeDashoffset=n==="reverse"?`${$[m]*t}`:`${$[m]*(1-t)}`,f&&(l.style.opacity=n==="reverse"?`${1-t}`:`${t}`),A&&y?l.style.stroke=he(A,y,t):y&&(l.style.stroke=y),h!==null&&g!==null?l.style.strokeWidth=`${h+(g-h)*t}`:g!==null&&(l.style.strokeWidth=`${g}`),b!==null&&w!==null?l.style.fillOpacity=`${b+(w-b)*t}`:w!==null&&(l.style.fillOpacity=`${w}`),O&&l.tagName.toLowerCase()==="path"&&k[m]&&l.setAttribute("d",De(k[m],O,t));});}function Ee(){if(W){e.style.clipPath=V(0);return}H.forEach((t,n)=>{t.style.strokeDasharray=`${$[n]}`,t.style.strokeDashoffset=I==="reverse"?"0":`${$[n]}`,f?t.style.opacity=I==="reverse"?"1":"0":t.style.opacity="",A&&(t.style.stroke=A),h!==null&&(t.style.strokeWidth=`${h}`),b!==null&&(t.style.fillOpacity=`${b}`),O&&t.tagName.toLowerCase()==="path"&&k[n]&&t.setAttribute("d",k[n]);});}if(H.forEach(t=>{ze(t);let n=ye(t);$.push(n),t.tagName.toLowerCase()==="path"?k.push(t.getAttribute("d")??""):k.push(""),s?(t.style.strokeDasharray=`${n}`,t.style.strokeDashoffset=I==="reverse"?`${n}`:"0",f&&(t.style.opacity="1"),y&&(t.style.stroke=y),g!==null&&(t.style.strokeWidth=`${g}`),w!==null&&(t.style.fillOpacity=`${w}`),O&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",O)):(t.style.strokeDasharray=`${n}`,t.style.strokeDashoffset=I==="reverse"?"0":`${n}`,f?t.style.opacity=I==="reverse"?"1":"0":t.style.opacity="",A&&(t.style.stroke=A),h!==null&&(t.style.strokeWidth=`${h}`),b!==null&&(t.style.fillOpacity=`${b}`));}),W){if(s)return e.style.clipPath=V(1),j?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};e.style.clipPath=V(0);}else if(s)return j?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};$e();function ee(){if(!J||P)return;let t=performance.now(),n=ue(),l=a;if(ie!==false){let i=t-xe,c=i>0?Math.abs(n-(Z<0?n:Z))/i:0;l=a*Math.max(.2,1+c*(typeof ie=="number"?ie:1)*.04);}Z=n,xe=t;let m=se?K===-1||n>=K?"forward":"reverse":I;K=n;let re=S-T,z=true;if(W){let i=ae(G(n,T,S,l));X&&!se&&(v=Math.max(v,i),i=v),Q=i;let c=m==="reverse"?1-i:i;e.style.clipPath=V(c),we?.(i),!F&&G(n,T,S,l)>0&&(F=true,ve?.()),i>=1&&!E?(E=true,j?.(),q<(_==="infinite"?1/0:_??0)&&(q++,U=setTimeout(()=>{v=-1,F=false,E=false,e.style.clipPath=V(0);},be))):i<1&&!X&&(E=false),M=requestAnimationFrame(ee);return}if(H.forEach((i,c)=>{let D=c*B*re,u=ae(G(n,T+D,S+D,l));X&&!se&&(v=Math.max(v,u),u=v),Q=u,i.style.strokeDashoffset=m==="reverse"?`${$[c]*u}`:`${$[c]*(1-u)}`,f&&(i.style.opacity=m==="reverse"?`${1-u}`:`${u}`),A&&y?i.style.stroke=he(A,y,u):y&&(i.style.stroke=y),h!==null&&g!==null?i.style.strokeWidth=`${h+(g-h)*u}`:g!==null&&(i.style.strokeWidth=`${g}`),b!==null&&w!==null?i.style.fillOpacity=`${b+(w-b)*u}`:w!==null&&(i.style.fillOpacity=`${w}`),O&&i.tagName.toLowerCase()==="path"&&k[c]&&i.setAttribute("d",De(k[c],O,u)),c===0&&we?.(u),u<1&&(z=false);}),oe){let i=ae(G(n,T,S,l));for(let c in oe){let D=parseFloat(c);i>=D&&!Y.has(D)&&(Y.add(D),oe[c]?.());}}!F&&G(n,T,S,l)>0&&(F=true,ve?.()),z&&!E?(E=true,j?.(),q<(_==="infinite"?1/0:_??0)&&(q++,U=setTimeout(()=>{v=-1,F=false,E=false,Y.clear(),Ee();},be))):!z&&!X&&(E=false),M=requestAnimationFrame(ee);}let fe=new IntersectionObserver(t=>{t.forEach(n=>{J=n.isIntersecting,J&&!P?M=requestAnimationFrame(ee):cancelAnimationFrame(M);});},{root:d??null,threshold:Fe,rootMargin:Pe}),pe;function te(){clearTimeout(pe),pe=setTimeout(()=>{H.forEach((t,n)=>{$[n]=ye(t),t.style.strokeDasharray=`${$[n]}`;}),$e();},150);}return window.addEventListener("resize",te),window.addEventListener("orientationchange",te),ge>0?setTimeout(()=>fe.observe(e),ge):fe.observe(e),{destroy(){cancelAnimationFrame(M),clearTimeout(U),fe.disconnect(),window.removeEventListener("resize",te),window.removeEventListener("orientationchange",te),clearTimeout(pe),ce?.remove();},replay(){v=-1,K=-1,Z=-1,F=false,E=false,q=0,P=false,Y.clear(),clearTimeout(U),Ee();},pause(){P=true,cancelAnimationFrame(M);},resume(){P&&(P=false,J&&(M=requestAnimationFrame(ee)));},seek(t){let n=Math.min(1,Math.max(0,t));Q=n,v=n,P=true,cancelAnimationFrame(M),We(n,I);},getProgress(){return Q}}}var Ie=class{constructor(){this.instance=null;}init(r,s={}){return this.destroy(),this.instance=Le(r,s),this}replay(){return this.instance?.replay(),this}destroy(){return this.instance?.destroy(),this.instance=null,this}};export{Ie as ScrollDrawRef};
@@ -0,0 +1,3 @@
1
+ 'use strict';var de={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)};function ye(e="top bottom"){let r=e.trim();if(/^\d+(\.\d+)?%$/.test(r))return {element:"top",viewport:r};let[n="top",s="bottom"]=r.split(/\s+/).filter(Boolean);return {element:n,viewport:s}}function Se(e,r,n,s){switch(s){case "top":return e+n;case "center":return e+n+r/2;case "bottom":return e+n+r;default:return e+n}}function De(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 ge(e){let r=e.tagName.toLowerCase();if(r==="rect"){let n=parseFloat(e.getAttribute("width")??"0"),s=parseFloat(e.getAttribute("height")??"0");return 2*(n+s)}if(r==="circle"){let n=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*n}return e.getTotalLength()}function We(e,r,n){return Math.min(n,Math.max(r,e))}function q(e,r,n,s){return n===r?0:We((e-r)/(n-r)*s,0,1)}function Te(e,r,n,s,a){let f=Se(e.top,e.height,r,s.element)-De(s.viewport,n),p=Se(e.top,e.height,r,a.element)-De(a.viewport,n);return {tStart:f,tEnd:p}}function ke(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 s=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(e);return s?[parseInt(s[1]),parseInt(s[2]),parseInt(s[3])]:null}function he(e,r,n){let s=ke(e),a=ke(r);return !s||!a?e:`rgb(${Math.round(s[0]+(a[0]-s[0])*n)},${Math.round(s[1]+(a[1]-s[1])*n)},${Math.round(s[2]+(a[2]-s[2])*n)})`}function Ie(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}function Ve(e){let r=e.getAttribute("stroke"),n=e.getAttribute("fill");!r||r==="none"?Ie("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&Ie("Element has a fill \u2014 it may obscure the stroke animation.",e);}function ze(e,r,n){let s=document.createElement("div");s.setAttribute("data-svg-scroll-draw-debug",""),s.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 a(){let f=n==="x"?window.scrollX:window.scrollY,p=e-f,M=r-f,B=n==="x";s.innerHTML=`
2
+ <div style="position:absolute;${B?`left:${p}px;top:0;bottom:0;border-left:2px dashed #22c55e;`:`top:${p}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;${B?`left:${M}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${M}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(s),window.addEventListener("scroll",a,{passive:true}),a(),s}function Me(e,r,n){let s=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),a=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,f=>{let p=parseFloat(f),M=s[a++]??p;return String(+(p+(M-p)*n).toFixed(4))})}function ne(e,r={}){if(typeof window>"u")return {destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};let n=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:s="path, polyline, line, polygon, rect, circle",speed:a=1,fade:f=false,easing:p="linear",trigger:M={},stagger:B=0,direction:L="forward",once:X=false,debug:Le=false,axis:x="y",scrollContainer:oe,autoReverse:se=false,delay:be=0,strokeColor:F,strokeWidth:N,fillOpacity:R,waypoints:ie,velocityScale:le=false,threshold:Oe=0,rootMargin:Pe="0px",repeat:_=0,repeatDelay:we=0,morphTo:O,clip:ae,onProgress:ve,onStart:xe,onComplete:J}=r,W=ae===true?"left":typeof ae=="string"?ae:false,ce=typeof p=="function"?p:de[p]??de.linear,Ce=ye(M.start??"top bottom"),Fe=ye(M.end??"bottom top"),d=typeof oe=="string"?document.querySelector(oe):oe??null,A=Array.isArray(F)?F[0]:null,y=Array.isArray(F)?F[1]:typeof F=="string"?F:null,g=Array.isArray(N)?N[0]:null,h=Array.isArray(N)?N[1]:typeof N=="number"?N:null,b=Array.isArray(R)?R[0]:null,w=Array.isArray(R)?R[1]:typeof R=="number"?R:null;function V(t){let o=t*100;switch(W){case "right":return `inset(0 0 0 ${100-o}%)`;case "top":return `inset(0 0 ${100-o}% 0)`;case "bottom":return `inset(${100-o}% 0 0 0)`;case "center":return `circle(${t*150}% at 50% 50%)`;default:return `inset(0 ${100-o}% 0 0)`}}let G=W?[]:Array.from(e.querySelectorAll(s)),E=[],S=[],D=0,k=0,$=false,P=false,T=0,j=false,v=-1,K=-1,C=false,Q=0,H=0,U,ue=null,Y=new Set,Z=-1,Ee=performance.now();function fe(){return d?x==="x"?d.scrollLeft:d.scrollTop:x==="x"?window.scrollX:window.scrollY}function Ne(){return d?x==="x"?d.clientWidth:d.clientHeight:x==="x"?window.innerWidth:window.innerHeight}function $e(){let t=e.getBoundingClientRect(),o,l,m;if(d){let z=d.getBoundingClientRect();o=x==="x"?t.left-z.left+d.scrollLeft:t.top-z.top+d.scrollTop,l=x==="x"?t.width:t.height,m=fe();}else o=x==="x"?t.left:t.top,l=x==="x"?t.width:t.height,m=fe();let re=Te({top:o,height:l},m,Ne(),Ce,Fe);D=re.tStart,k=re.tEnd,Le&&process.env.NODE_ENV!=="production"&&(ue?.remove(),ue=ze(D,k,x));}function Re(t,o){if(W){let l=o==="reverse"?1-t:t;e.style.clipPath=V(l);return}G.forEach((l,m)=>{l.style.strokeDashoffset=o==="reverse"?`${E[m]*t}`:`${E[m]*(1-t)}`,f&&(l.style.opacity=o==="reverse"?`${1-t}`:`${t}`),A&&y?l.style.stroke=he(A,y,t):y&&(l.style.stroke=y),g!==null&&h!==null?l.style.strokeWidth=`${g+(h-g)*t}`:h!==null&&(l.style.strokeWidth=`${h}`),b!==null&&w!==null?l.style.fillOpacity=`${b+(w-b)*t}`:w!==null&&(l.style.fillOpacity=`${w}`),O&&l.tagName.toLowerCase()==="path"&&S[m]&&l.setAttribute("d",Me(S[m],O,t));});}function Ae(){if(W){e.style.clipPath=V(0);return}G.forEach((t,o)=>{t.style.strokeDasharray=`${E[o]}`,t.style.strokeDashoffset=L==="reverse"?"0":`${E[o]}`,f?t.style.opacity=L==="reverse"?"1":"0":t.style.opacity="",A&&(t.style.stroke=A),g!==null&&(t.style.strokeWidth=`${g}`),b!==null&&(t.style.fillOpacity=`${b}`),O&&t.tagName.toLowerCase()==="path"&&S[o]&&t.setAttribute("d",S[o]);});}if(G.forEach(t=>{Ve(t);let o=ge(t);E.push(o),t.tagName.toLowerCase()==="path"?S.push(t.getAttribute("d")??""):S.push(""),n?(t.style.strokeDasharray=`${o}`,t.style.strokeDashoffset=L==="reverse"?`${o}`:"0",f&&(t.style.opacity="1"),y&&(t.style.stroke=y),h!==null&&(t.style.strokeWidth=`${h}`),w!==null&&(t.style.fillOpacity=`${w}`),O&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",O)):(t.style.strokeDasharray=`${o}`,t.style.strokeDashoffset=L==="reverse"?"0":`${o}`,f?t.style.opacity=L==="reverse"?"1":"0":t.style.opacity="",A&&(t.style.stroke=A),g!==null&&(t.style.strokeWidth=`${g}`),b!==null&&(t.style.fillOpacity=`${b}`));}),W){if(n)return e.style.clipPath=V(1),J?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};e.style.clipPath=V(0);}else if(n)return J?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};$e();function ee(){if(!j||C)return;let t=performance.now(),o=fe(),l=a;if(le!==false){let i=t-Ee,c=i>0?Math.abs(o-(Z<0?o:Z))/i:0;l=a*Math.max(.2,1+c*(typeof le=="number"?le:1)*.04);}Z=o,Ee=t;let m=se?K===-1||o>=K?"forward":"reverse":L;K=o;let re=k-D,z=true;if(W){let i=ce(q(o,D,k,l));X&&!se&&(v=Math.max(v,i),i=v),Q=i;let c=m==="reverse"?1-i:i;e.style.clipPath=V(c),ve?.(i),!P&&q(o,D,k,l)>0&&(P=true,xe?.()),i>=1&&!$?($=true,J?.(),H<(_==="infinite"?1/0:_??0)&&(H++,U=setTimeout(()=>{v=-1,P=false,$=false,e.style.clipPath=V(0);},we))):i<1&&!X&&($=false),T=requestAnimationFrame(ee);return}if(G.forEach((i,c)=>{let I=c*B*re,u=ce(q(o,D+I,k+I,l));X&&!se&&(v=Math.max(v,u),u=v),Q=u,i.style.strokeDashoffset=m==="reverse"?`${E[c]*u}`:`${E[c]*(1-u)}`,f&&(i.style.opacity=m==="reverse"?`${1-u}`:`${u}`),A&&y?i.style.stroke=he(A,y,u):y&&(i.style.stroke=y),g!==null&&h!==null?i.style.strokeWidth=`${g+(h-g)*u}`:h!==null&&(i.style.strokeWidth=`${h}`),b!==null&&w!==null?i.style.fillOpacity=`${b+(w-b)*u}`:w!==null&&(i.style.fillOpacity=`${w}`),O&&i.tagName.toLowerCase()==="path"&&S[c]&&i.setAttribute("d",Me(S[c],O,u)),c===0&&ve?.(u),u<1&&(z=false);}),ie){let i=ce(q(o,D,k,l));for(let c in ie){let I=parseFloat(c);i>=I&&!Y.has(I)&&(Y.add(I),ie[c]?.());}}!P&&q(o,D,k,l)>0&&(P=true,xe?.()),z&&!$?($=true,J?.(),H<(_==="infinite"?1/0:_??0)&&(H++,U=setTimeout(()=>{v=-1,P=false,$=false,Y.clear(),Ae();},we))):!z&&!X&&($=false),T=requestAnimationFrame(ee);}let pe=new IntersectionObserver(t=>{t.forEach(o=>{j=o.isIntersecting,j&&!C?T=requestAnimationFrame(ee):cancelAnimationFrame(T);});},{root:d??null,threshold:Oe,rootMargin:Pe}),me;function te(){clearTimeout(me),me=setTimeout(()=>{G.forEach((t,o)=>{E[o]=ge(t),t.style.strokeDasharray=`${E[o]}`;}),$e();},150);}return window.addEventListener("resize",te),window.addEventListener("orientationchange",te),be>0?setTimeout(()=>pe.observe(e),be):pe.observe(e),{destroy(){cancelAnimationFrame(T),clearTimeout(U),pe.disconnect(),window.removeEventListener("resize",te),window.removeEventListener("orientationchange",te),clearTimeout(me),ue?.remove();},replay(){v=-1,K=-1,Z=-1,P=false,$=false,H=0,C=false,Y.clear(),clearTimeout(U),Ae();},pause(){C=true,cancelAnimationFrame(T);},resume(){C&&(C=false,j&&(T=requestAnimationFrame(ee)));},seek(t){let o=Math.min(1,Math.max(0,t));Q=o,v=o,C=true,cancelAnimationFrame(T),Re(o,L);},getProgress(){return Q}}}function qe(e,r){let n={destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};if(typeof window>"u")return n;let s=typeof e=="string"?document.querySelector(e):e;return s?ne(s,r):(console.warn("[svg-scroll-draw] Container not found:",e),n)}function je(e=document){return Array.from(e.querySelectorAll("[data-scroll-draw]")).map(r=>{let n={};try{let s=r.dataset.scrollDrawOptions??r.dataset.scrollDrawoptions??"";s&&(n=JSON.parse(s));}catch{}return ne(r,n)})}exports.initScrollDraw=je;exports.scrollDraw=qe;
@@ -0,0 +1,87 @@
1
+ type EasingName = 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'spring';
2
+ interface TriggerConfig {
3
+ start?: string;
4
+ end?: string;
5
+ }
6
+ interface ScrollDrawOptions {
7
+ selector?: string;
8
+ speed?: number;
9
+ fade?: boolean;
10
+ easing?: EasingName | ((t: number) => number);
11
+ trigger?: TriggerConfig;
12
+ stagger?: number;
13
+ direction?: 'forward' | 'reverse';
14
+ once?: boolean;
15
+ debug?: boolean;
16
+ /** Scroll axis to track. 'y' (default) for vertical, 'x' for horizontal. */
17
+ axis?: 'x' | 'y';
18
+ /** CSS selector or Element for a custom scroll container (default: window). */
19
+ scrollContainer?: string | Element;
20
+ /** Automatically reverse the animation when the user scrolls back up. */
21
+ autoReverse?: boolean;
22
+ /** Delay in milliseconds before the engine starts observing. */
23
+ delay?: number;
24
+ /** Animate stroke color. Single string = static override. Tuple = interpolate from → to. */
25
+ strokeColor?: string | [string, string];
26
+ /** Animate stroke width. Single number = static override. Tuple = interpolate from → to. */
27
+ strokeWidth?: number | [number, number];
28
+ /** Animate fill opacity. Single number = static override. Tuple [from, to] = interpolate as the path draws. Use [0, 1] to flood fill in sync with the stroke draw. */
29
+ fillOpacity?: number | [number, number];
30
+ /**
31
+ * Reveal the container using CSS clip-path instead of stroke-dashoffset.
32
+ * Works on any content — SVG, images, text, divs.
33
+ * `true` defaults to `'left'`. Values: `'left' | 'right' | 'top' | 'bottom' | 'center'`.
34
+ */
35
+ clip?: boolean | 'left' | 'right' | 'top' | 'bottom' | 'center';
36
+ /** Fire callbacks at specific progress thresholds (0–1). Resets on replay(). */
37
+ waypoints?: Record<number, () => void>;
38
+ /** Scale animation speed by scroll velocity — faster scrolling = faster draw. Pass a number to control sensitivity (default 1). */
39
+ velocityScale?: boolean | number;
40
+ /** IntersectionObserver threshold (0–1). Default 0. */
41
+ threshold?: number;
42
+ /** IntersectionObserver rootMargin. Default "0px". */
43
+ rootMargin?: string;
44
+ /** Repeat the animation N times after completion. Use 'infinite' to loop forever. */
45
+ repeat?: number | 'infinite';
46
+ /** Milliseconds to wait between repeats. Default 0. */
47
+ repeatDelay?: number;
48
+ /** Target path `d` attribute to morph toward as the animation progresses. Paths must have compatible structures. */
49
+ morphTo?: string;
50
+ onProgress?: (alpha: number) => void;
51
+ onStart?: () => void;
52
+ onComplete?: () => void;
53
+ }
54
+ interface ScrollDrawInstance {
55
+ destroy: () => void;
56
+ /** Reset and replay the animation from the beginning. */
57
+ replay: () => void;
58
+ /** Pause the animation at the current progress. */
59
+ pause: () => void;
60
+ /** Resume a paused animation. */
61
+ resume: () => void;
62
+ /** Jump to a specific progress value (0–1) and pause. */
63
+ seek: (progress: number) => void;
64
+ /** Returns current draw progress (0–1). */
65
+ getProgress: () => number;
66
+ }
67
+
68
+ declare function scrollDraw(target: string | Element, options?: ScrollDrawOptions): ScrollDrawInstance;
69
+
70
+ /**
71
+ * Auto-initialises all elements with a [data-scroll-draw] attribute on the page.
72
+ * Options are read from the data-scroll-draw-options JSON attribute.
73
+ *
74
+ * @example
75
+ * // In your Astro component:
76
+ * <div data-scroll-draw data-scroll-draw-options='{"easing":"ease-out","fade":true}'>
77
+ * <svg>...</svg>
78
+ * </div>
79
+ *
80
+ * <script>
81
+ * import { initScrollDraw } from 'svg-scroll-draw/astro';
82
+ * initScrollDraw();
83
+ * </script>
84
+ */
85
+ declare function initScrollDraw(root?: Element | Document): ScrollDrawInstance[];
86
+
87
+ export { type ScrollDrawInstance, type ScrollDrawOptions, initScrollDraw, scrollDraw };
@@ -0,0 +1,87 @@
1
+ type EasingName = 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'spring';
2
+ interface TriggerConfig {
3
+ start?: string;
4
+ end?: string;
5
+ }
6
+ interface ScrollDrawOptions {
7
+ selector?: string;
8
+ speed?: number;
9
+ fade?: boolean;
10
+ easing?: EasingName | ((t: number) => number);
11
+ trigger?: TriggerConfig;
12
+ stagger?: number;
13
+ direction?: 'forward' | 'reverse';
14
+ once?: boolean;
15
+ debug?: boolean;
16
+ /** Scroll axis to track. 'y' (default) for vertical, 'x' for horizontal. */
17
+ axis?: 'x' | 'y';
18
+ /** CSS selector or Element for a custom scroll container (default: window). */
19
+ scrollContainer?: string | Element;
20
+ /** Automatically reverse the animation when the user scrolls back up. */
21
+ autoReverse?: boolean;
22
+ /** Delay in milliseconds before the engine starts observing. */
23
+ delay?: number;
24
+ /** Animate stroke color. Single string = static override. Tuple = interpolate from → to. */
25
+ strokeColor?: string | [string, string];
26
+ /** Animate stroke width. Single number = static override. Tuple = interpolate from → to. */
27
+ strokeWidth?: number | [number, number];
28
+ /** Animate fill opacity. Single number = static override. Tuple [from, to] = interpolate as the path draws. Use [0, 1] to flood fill in sync with the stroke draw. */
29
+ fillOpacity?: number | [number, number];
30
+ /**
31
+ * Reveal the container using CSS clip-path instead of stroke-dashoffset.
32
+ * Works on any content — SVG, images, text, divs.
33
+ * `true` defaults to `'left'`. Values: `'left' | 'right' | 'top' | 'bottom' | 'center'`.
34
+ */
35
+ clip?: boolean | 'left' | 'right' | 'top' | 'bottom' | 'center';
36
+ /** Fire callbacks at specific progress thresholds (0–1). Resets on replay(). */
37
+ waypoints?: Record<number, () => void>;
38
+ /** Scale animation speed by scroll velocity — faster scrolling = faster draw. Pass a number to control sensitivity (default 1). */
39
+ velocityScale?: boolean | number;
40
+ /** IntersectionObserver threshold (0–1). Default 0. */
41
+ threshold?: number;
42
+ /** IntersectionObserver rootMargin. Default "0px". */
43
+ rootMargin?: string;
44
+ /** Repeat the animation N times after completion. Use 'infinite' to loop forever. */
45
+ repeat?: number | 'infinite';
46
+ /** Milliseconds to wait between repeats. Default 0. */
47
+ repeatDelay?: number;
48
+ /** Target path `d` attribute to morph toward as the animation progresses. Paths must have compatible structures. */
49
+ morphTo?: string;
50
+ onProgress?: (alpha: number) => void;
51
+ onStart?: () => void;
52
+ onComplete?: () => void;
53
+ }
54
+ interface ScrollDrawInstance {
55
+ destroy: () => void;
56
+ /** Reset and replay the animation from the beginning. */
57
+ replay: () => void;
58
+ /** Pause the animation at the current progress. */
59
+ pause: () => void;
60
+ /** Resume a paused animation. */
61
+ resume: () => void;
62
+ /** Jump to a specific progress value (0–1) and pause. */
63
+ seek: (progress: number) => void;
64
+ /** Returns current draw progress (0–1). */
65
+ getProgress: () => number;
66
+ }
67
+
68
+ declare function scrollDraw(target: string | Element, options?: ScrollDrawOptions): ScrollDrawInstance;
69
+
70
+ /**
71
+ * Auto-initialises all elements with a [data-scroll-draw] attribute on the page.
72
+ * Options are read from the data-scroll-draw-options JSON attribute.
73
+ *
74
+ * @example
75
+ * // In your Astro component:
76
+ * <div data-scroll-draw data-scroll-draw-options='{"easing":"ease-out","fade":true}'>
77
+ * <svg>...</svg>
78
+ * </div>
79
+ *
80
+ * <script>
81
+ * import { initScrollDraw } from 'svg-scroll-draw/astro';
82
+ * initScrollDraw();
83
+ * </script>
84
+ */
85
+ declare function initScrollDraw(root?: Element | Document): ScrollDrawInstance[];
86
+
87
+ export { type ScrollDrawInstance, type ScrollDrawOptions, initScrollDraw, scrollDraw };
@@ -0,0 +1,3 @@
1
+ var de={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)};function ye(e="top bottom"){let r=e.trim();if(/^\d+(\.\d+)?%$/.test(r))return {element:"top",viewport:r};let[n="top",s="bottom"]=r.split(/\s+/).filter(Boolean);return {element:n,viewport:s}}function Se(e,r,n,s){switch(s){case "top":return e+n;case "center":return e+n+r/2;case "bottom":return e+n+r;default:return e+n}}function De(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 ge(e){let r=e.tagName.toLowerCase();if(r==="rect"){let n=parseFloat(e.getAttribute("width")??"0"),s=parseFloat(e.getAttribute("height")??"0");return 2*(n+s)}if(r==="circle"){let n=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*n}return e.getTotalLength()}function We(e,r,n){return Math.min(n,Math.max(r,e))}function q(e,r,n,s){return n===r?0:We((e-r)/(n-r)*s,0,1)}function Te(e,r,n,s,a){let f=Se(e.top,e.height,r,s.element)-De(s.viewport,n),p=Se(e.top,e.height,r,a.element)-De(a.viewport,n);return {tStart:f,tEnd:p}}function ke(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 s=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(e);return s?[parseInt(s[1]),parseInt(s[2]),parseInt(s[3])]:null}function he(e,r,n){let s=ke(e),a=ke(r);return !s||!a?e:`rgb(${Math.round(s[0]+(a[0]-s[0])*n)},${Math.round(s[1]+(a[1]-s[1])*n)},${Math.round(s[2]+(a[2]-s[2])*n)})`}function Ie(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}function Ve(e){let r=e.getAttribute("stroke"),n=e.getAttribute("fill");!r||r==="none"?Ie("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&Ie("Element has a fill \u2014 it may obscure the stroke animation.",e);}function ze(e,r,n){let s=document.createElement("div");s.setAttribute("data-svg-scroll-draw-debug",""),s.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 a(){let f=n==="x"?window.scrollX:window.scrollY,p=e-f,M=r-f,B=n==="x";s.innerHTML=`
2
+ <div style="position:absolute;${B?`left:${p}px;top:0;bottom:0;border-left:2px dashed #22c55e;`:`top:${p}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;${B?`left:${M}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${M}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(s),window.addEventListener("scroll",a,{passive:true}),a(),s}function Me(e,r,n){let s=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),a=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,f=>{let p=parseFloat(f),M=s[a++]??p;return String(+(p+(M-p)*n).toFixed(4))})}function ne(e,r={}){if(typeof window>"u")return {destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};let n=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:s="path, polyline, line, polygon, rect, circle",speed:a=1,fade:f=false,easing:p="linear",trigger:M={},stagger:B=0,direction:L="forward",once:X=false,debug:Le=false,axis:x="y",scrollContainer:oe,autoReverse:se=false,delay:be=0,strokeColor:F,strokeWidth:N,fillOpacity:R,waypoints:ie,velocityScale:le=false,threshold:Oe=0,rootMargin:Pe="0px",repeat:_=0,repeatDelay:we=0,morphTo:O,clip:ae,onProgress:ve,onStart:xe,onComplete:J}=r,W=ae===true?"left":typeof ae=="string"?ae:false,ce=typeof p=="function"?p:de[p]??de.linear,Ce=ye(M.start??"top bottom"),Fe=ye(M.end??"bottom top"),d=typeof oe=="string"?document.querySelector(oe):oe??null,A=Array.isArray(F)?F[0]:null,y=Array.isArray(F)?F[1]:typeof F=="string"?F:null,g=Array.isArray(N)?N[0]:null,h=Array.isArray(N)?N[1]:typeof N=="number"?N:null,b=Array.isArray(R)?R[0]:null,w=Array.isArray(R)?R[1]:typeof R=="number"?R:null;function V(t){let o=t*100;switch(W){case "right":return `inset(0 0 0 ${100-o}%)`;case "top":return `inset(0 0 ${100-o}% 0)`;case "bottom":return `inset(${100-o}% 0 0 0)`;case "center":return `circle(${t*150}% at 50% 50%)`;default:return `inset(0 ${100-o}% 0 0)`}}let G=W?[]:Array.from(e.querySelectorAll(s)),E=[],S=[],D=0,k=0,$=false,P=false,T=0,j=false,v=-1,K=-1,C=false,Q=0,H=0,U,ue=null,Y=new Set,Z=-1,Ee=performance.now();function fe(){return d?x==="x"?d.scrollLeft:d.scrollTop:x==="x"?window.scrollX:window.scrollY}function Ne(){return d?x==="x"?d.clientWidth:d.clientHeight:x==="x"?window.innerWidth:window.innerHeight}function $e(){let t=e.getBoundingClientRect(),o,l,m;if(d){let z=d.getBoundingClientRect();o=x==="x"?t.left-z.left+d.scrollLeft:t.top-z.top+d.scrollTop,l=x==="x"?t.width:t.height,m=fe();}else o=x==="x"?t.left:t.top,l=x==="x"?t.width:t.height,m=fe();let re=Te({top:o,height:l},m,Ne(),Ce,Fe);D=re.tStart,k=re.tEnd,Le&&process.env.NODE_ENV!=="production"&&(ue?.remove(),ue=ze(D,k,x));}function Re(t,o){if(W){let l=o==="reverse"?1-t:t;e.style.clipPath=V(l);return}G.forEach((l,m)=>{l.style.strokeDashoffset=o==="reverse"?`${E[m]*t}`:`${E[m]*(1-t)}`,f&&(l.style.opacity=o==="reverse"?`${1-t}`:`${t}`),A&&y?l.style.stroke=he(A,y,t):y&&(l.style.stroke=y),g!==null&&h!==null?l.style.strokeWidth=`${g+(h-g)*t}`:h!==null&&(l.style.strokeWidth=`${h}`),b!==null&&w!==null?l.style.fillOpacity=`${b+(w-b)*t}`:w!==null&&(l.style.fillOpacity=`${w}`),O&&l.tagName.toLowerCase()==="path"&&S[m]&&l.setAttribute("d",Me(S[m],O,t));});}function Ae(){if(W){e.style.clipPath=V(0);return}G.forEach((t,o)=>{t.style.strokeDasharray=`${E[o]}`,t.style.strokeDashoffset=L==="reverse"?"0":`${E[o]}`,f?t.style.opacity=L==="reverse"?"1":"0":t.style.opacity="",A&&(t.style.stroke=A),g!==null&&(t.style.strokeWidth=`${g}`),b!==null&&(t.style.fillOpacity=`${b}`),O&&t.tagName.toLowerCase()==="path"&&S[o]&&t.setAttribute("d",S[o]);});}if(G.forEach(t=>{Ve(t);let o=ge(t);E.push(o),t.tagName.toLowerCase()==="path"?S.push(t.getAttribute("d")??""):S.push(""),n?(t.style.strokeDasharray=`${o}`,t.style.strokeDashoffset=L==="reverse"?`${o}`:"0",f&&(t.style.opacity="1"),y&&(t.style.stroke=y),h!==null&&(t.style.strokeWidth=`${h}`),w!==null&&(t.style.fillOpacity=`${w}`),O&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",O)):(t.style.strokeDasharray=`${o}`,t.style.strokeDashoffset=L==="reverse"?"0":`${o}`,f?t.style.opacity=L==="reverse"?"1":"0":t.style.opacity="",A&&(t.style.stroke=A),g!==null&&(t.style.strokeWidth=`${g}`),b!==null&&(t.style.fillOpacity=`${b}`));}),W){if(n)return e.style.clipPath=V(1),J?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};e.style.clipPath=V(0);}else if(n)return J?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};$e();function ee(){if(!j||C)return;let t=performance.now(),o=fe(),l=a;if(le!==false){let i=t-Ee,c=i>0?Math.abs(o-(Z<0?o:Z))/i:0;l=a*Math.max(.2,1+c*(typeof le=="number"?le:1)*.04);}Z=o,Ee=t;let m=se?K===-1||o>=K?"forward":"reverse":L;K=o;let re=k-D,z=true;if(W){let i=ce(q(o,D,k,l));X&&!se&&(v=Math.max(v,i),i=v),Q=i;let c=m==="reverse"?1-i:i;e.style.clipPath=V(c),ve?.(i),!P&&q(o,D,k,l)>0&&(P=true,xe?.()),i>=1&&!$?($=true,J?.(),H<(_==="infinite"?1/0:_??0)&&(H++,U=setTimeout(()=>{v=-1,P=false,$=false,e.style.clipPath=V(0);},we))):i<1&&!X&&($=false),T=requestAnimationFrame(ee);return}if(G.forEach((i,c)=>{let I=c*B*re,u=ce(q(o,D+I,k+I,l));X&&!se&&(v=Math.max(v,u),u=v),Q=u,i.style.strokeDashoffset=m==="reverse"?`${E[c]*u}`:`${E[c]*(1-u)}`,f&&(i.style.opacity=m==="reverse"?`${1-u}`:`${u}`),A&&y?i.style.stroke=he(A,y,u):y&&(i.style.stroke=y),g!==null&&h!==null?i.style.strokeWidth=`${g+(h-g)*u}`:h!==null&&(i.style.strokeWidth=`${h}`),b!==null&&w!==null?i.style.fillOpacity=`${b+(w-b)*u}`:w!==null&&(i.style.fillOpacity=`${w}`),O&&i.tagName.toLowerCase()==="path"&&S[c]&&i.setAttribute("d",Me(S[c],O,u)),c===0&&ve?.(u),u<1&&(z=false);}),ie){let i=ce(q(o,D,k,l));for(let c in ie){let I=parseFloat(c);i>=I&&!Y.has(I)&&(Y.add(I),ie[c]?.());}}!P&&q(o,D,k,l)>0&&(P=true,xe?.()),z&&!$?($=true,J?.(),H<(_==="infinite"?1/0:_??0)&&(H++,U=setTimeout(()=>{v=-1,P=false,$=false,Y.clear(),Ae();},we))):!z&&!X&&($=false),T=requestAnimationFrame(ee);}let pe=new IntersectionObserver(t=>{t.forEach(o=>{j=o.isIntersecting,j&&!C?T=requestAnimationFrame(ee):cancelAnimationFrame(T);});},{root:d??null,threshold:Oe,rootMargin:Pe}),me;function te(){clearTimeout(me),me=setTimeout(()=>{G.forEach((t,o)=>{E[o]=ge(t),t.style.strokeDasharray=`${E[o]}`;}),$e();},150);}return window.addEventListener("resize",te),window.addEventListener("orientationchange",te),be>0?setTimeout(()=>pe.observe(e),be):pe.observe(e),{destroy(){cancelAnimationFrame(T),clearTimeout(U),pe.disconnect(),window.removeEventListener("resize",te),window.removeEventListener("orientationchange",te),clearTimeout(me),ue?.remove();},replay(){v=-1,K=-1,Z=-1,P=false,$=false,H=0,C=false,Y.clear(),clearTimeout(U),Ae();},pause(){C=true,cancelAnimationFrame(T);},resume(){C&&(C=false,j&&(T=requestAnimationFrame(ee)));},seek(t){let o=Math.min(1,Math.max(0,t));Q=o,v=o,C=true,cancelAnimationFrame(T),Re(o,L);},getProgress(){return Q}}}function qe(e,r){let n={destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};if(typeof window>"u")return n;let s=typeof e=="string"?document.querySelector(e):e;return s?ne(s,r):(console.warn("[svg-scroll-draw] Container not found:",e),n)}function je(e=document){return Array.from(e.querySelectorAll("[data-scroll-draw]")).map(r=>{let n={};try{let s=r.dataset.scrollDrawOptions??r.dataset.scrollDrawoptions??"";s&&(n=JSON.parse(s));}catch{}return ne(r,n)})}export{je as initScrollDraw,qe as scrollDraw};
@@ -1,3 +1,3 @@
1
- "use strict";var SvgScrollDraw=(()=>{var _=Object.defineProperty;var be=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var we=Object.prototype.hasOwnProperty;var ve=(e,t)=>{for(var r in t)_(e,r,{get:t[r],enumerable:!0})},xe=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ye(t))!we.call(e,s)&&s!==r&&_(e,s,{get:()=>t[s],enumerable:!(n=be(t,s))||n.enumerable});return e};var Ee=e=>xe(_({},"__esModule",{value:!0}),e);var De={};ve(De,{scrollDraw:()=>$e});var j={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)};function J(e="top bottom"){let t=e.trim();if(/^\d+(\.\d+)?%$/.test(t))return{element:"top",viewport:t};let[r="top",n="bottom"]=t.split(/\s+/).filter(Boolean);return{element:r,viewport:n}}function oe(e,t,r,n){switch(n){case"top":return e+r;case"center":return e+r+t/2;case"bottom":return e+r+t;default:return e+r}}function se(e,t){if(/^\d+(\.\d+)?%$/.test(e))return t*(parseFloat(e)/100);switch(e){case"top":return 0;case"center":return t/2;case"bottom":return t;default:return t}}function K(e){let t=e.tagName.toLowerCase();if(t==="rect"){let r=parseFloat(e.getAttribute("width")??"0"),n=parseFloat(e.getAttribute("height")??"0");return 2*(r+n)}if(t==="circle"){let r=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*r}return e.getTotalLength()}function Se(e,t,r){return Math.min(r,Math.max(t,e))}function z(e,t,r,n){return r===t?0:Se((e-t)/(r-t)*n,0,1)}function le(e,t,r,n,s){let l=oe(e.top,e.height,t,n.element)-se(n.viewport,r),a=oe(e.top,e.height,t,s.element)-se(s.viewport,r);return{tStart:l,tEnd:a}}function ie(e){let t=/^#([a-f\d])([a-f\d])([a-f\d])$/i.exec(e);if(t)return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)];let r=/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(r)return[parseInt(r[1],16),parseInt(r[2],16),parseInt(r[3],16)];let n=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(e);return n?[parseInt(n[1]),parseInt(n[2]),parseInt(n[3])]:null}function ae(e,t,r){let n=ie(e),s=ie(t);return!n||!s?e:`rgb(${Math.round(n[0]+(s[0]-n[0])*r)},${Math.round(n[1]+(s[1]-n[1])*r)},${Math.round(n[2]+(s[2]-n[2])*r)})`}function ce(e,t){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,t)}function Ae(e){let t=e.getAttribute("stroke"),r=e.getAttribute("fill");!t||t==="none"?ce("Element has no stroke \u2014 path will not be visible.",e):r&&r!=="none"&&r!=="transparent"&&ce("Element has a fill \u2014 it may obscure the stroke animation.",e)}function ke(e,t,r){let n=document.createElement("div");n.setAttribute("data-svg-scroll-draw-debug",""),n.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 s(){let l=r==="x"?window.scrollX:window.scrollY,a=e-l,m=t-l,I=r==="x";n.innerHTML=`
2
- <div style="position:absolute;${I?`left:${a}px;top:0;bottom:0;border-left:2px dashed #22c55e;`:`top:${a}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;${I?`left:${m}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${m}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(n),window.addEventListener("scroll",s,{passive:!0}),s(),n}function W(e,t={}){if(typeof window>"u")return{destroy:()=>{},replay:()=>{}};let r=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:n="path, polyline, line, polygon, rect, circle",speed:s=1,fade:l=!1,easing:a="linear",trigger:m={},stagger:I=0,direction:y="forward",once:U=!1,debug:ue=!1,axis:d="y",scrollContainer:G,autoReverse:Y=!1,delay:Z=0,strokeColor:w,strokeWidth:v,waypoints:V,onProgress:fe,onStart:pe,onComplete:ee}=t,te=typeof a=="function"?a:j[a]??j.linear,de=J(m.start??"top bottom"),me=J(m.end??"bottom top"),c=typeof G=="string"?document.querySelector(G):G??null,x=Array.isArray(w)?w[0]:null,E=Array.isArray(w)?w[1]:typeof w=="string"?w:null,g=Array.isArray(v)?v[0]:null,S=Array.isArray(v)?v[1]:typeof v=="number"?v:null,T=Array.from(e.querySelectorAll(n)),h=[],A=0,k=0,L=!1,N=!1,M=0,P=!1,C=-1,F=-1,R=null,q=new Set;function B(){return c?d==="x"?c.scrollLeft:c.scrollTop:d==="x"?window.scrollX:window.scrollY}function ge(){return c?d==="x"?c.clientWidth:c.clientHeight:d==="x"?window.innerWidth:window.innerHeight}function re(){let o=e.getBoundingClientRect(),i,D,b;if(c){let f=c.getBoundingClientRect();i=d==="x"?o.left-f.left+c.scrollLeft:o.top-f.top+c.scrollTop,D=d==="x"?o.width:o.height,b=B()}else i=d==="x"?o.left:o.top,D=d==="x"?o.width:o.height,b=B();let u=le({top:i,height:D},b,ge(),de,me);A=u.tStart,k=u.tEnd,ue&&process.env.NODE_ENV!=="production"&&(R?.remove(),R=ke(A,k,d))}function he(){T.forEach((o,i)=>{o.style.strokeDasharray=`${h[i]}`,o.style.strokeDashoffset=y==="reverse"?"0":`${h[i]}`,l?o.style.opacity=y==="reverse"?"1":"0":o.style.opacity="",x&&(o.style.stroke=x),g!==null&&(o.style.strokeWidth=`${g}`)})}if(T.forEach(o=>{Ae(o);let i=K(o);h.push(i),r?(o.style.strokeDasharray=`${i}`,o.style.strokeDashoffset=y==="reverse"?`${i}`:"0",l&&(o.style.opacity="1"),E&&(o.style.stroke=E),S!==null&&(o.style.strokeWidth=`${S}`)):(o.style.strokeDasharray=`${i}`,o.style.strokeDashoffset=y==="reverse"?"0":`${i}`,l?o.style.opacity=y==="reverse"?"1":"0":o.style.opacity="",x&&(o.style.stroke=x),g!==null&&(o.style.strokeWidth=`${g}`))}),r)return ee?.(),{destroy:()=>{},replay:()=>{}};re();function ne(){if(!P)return;let o=B(),i=Y?F===-1||o>=F?"forward":"reverse":y;F=o;let D=k-A,b=!0;if(T.forEach((u,f)=>{let $=f*I*D,p=te(z(o,A+$,k+$,s));U&&!Y&&(C=Math.max(C,p),p=C),u.style.strokeDashoffset=i==="reverse"?`${h[f]*p}`:`${h[f]*(1-p)}`,l&&(u.style.opacity=i==="reverse"?`${1-p}`:`${p}`),x&&E?u.style.stroke=ae(x,E,p):E&&(u.style.stroke=E),g!==null&&S!==null?u.style.strokeWidth=`${g+(S-g)*p}`:S!==null&&(u.style.strokeWidth=`${S}`),f===0&&fe?.(p),p<1&&(b=!1)}),V){let u=te(z(o,A,k,s));for(let f in V){let $=parseFloat(f);u>=$&&!q.has($)&&(q.add($),V[f]?.())}}!N&&z(o,A,k,s)>0&&(N=!0,pe?.()),b&&!L?(L=!0,ee?.()):!b&&!U&&(L=!1),M=requestAnimationFrame(ne)}let H=new IntersectionObserver(o=>{o.forEach(i=>{P=i.isIntersecting,P?M=requestAnimationFrame(ne):cancelAnimationFrame(M)})},{root:c??null}),X;function O(){clearTimeout(X),X=setTimeout(()=>{T.forEach((o,i)=>{h[i]=K(o),o.style.strokeDasharray=`${h[i]}`}),re()},150)}return window.addEventListener("resize",O),window.addEventListener("orientationchange",O),Z>0?setTimeout(()=>H.observe(e),Z):H.observe(e),{destroy(){cancelAnimationFrame(M),H.disconnect(),window.removeEventListener("resize",O),window.removeEventListener("orientationchange",O),clearTimeout(X),R?.remove()},replay(){C=-1,F=-1,N=!1,L=!1,q.clear(),he()}}}function $e(e,t){let r={destroy:()=>{},replay:()=>{}};if(typeof window>"u")return r;let n=typeof e=="string"?document.querySelector(e):e;return n?W(n,t):(console.warn("[svg-scroll-draw] Container not found:",e),r)}var Q=class extends HTMLElement{constructor(){super(...arguments);this.instance=null}connectedCallback(){let r={},n=this.getAttribute("speed"),s=this.getAttribute("easing"),l=this.getAttribute("stagger"),a=this.getAttribute("direction"),m=this.getAttribute("selector");n&&(r.speed=parseFloat(n)),s&&(r.easing=s),l&&(r.stagger=parseFloat(l)),a&&(r.direction=a),m&&(r.selector=m),this.hasAttribute("fade")&&(r.fade=this.getAttribute("fade")!=="false"),this.instance=W(this,r)}disconnectedCallback(){this.instance?.destroy(),this.instance=null}};typeof customElements<"u"&&!customElements.get("scroll-draw")&&customElements.define("scroll-draw",Q);return Ee(De);})();
1
+ "use strict";var SvgScrollDraw=(()=>{var de=Object.defineProperty;var ze=Object.getOwnPropertyDescriptor;var Ge=Object.getOwnPropertyNames;var He=Object.prototype.hasOwnProperty;var qe=(e,r)=>{for(var n in r)de(e,n,{get:r[n],enumerable:!0})},Be=(e,r,n,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let l of Ge(r))!He.call(e,l)&&l!==n&&de(e,l,{get:()=>r[l],enumerable:!(o=ze(r,l))||o.enumerable});return e};var Xe=e=>Be(de({},"__esModule",{value:!0}),e);var Qe={};qe(Qe,{scrollDraw:()=>Ke});var ye={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)};function ge(e="top bottom"){let r=e.trim();if(/^\d+(\.\d+)?%$/.test(r))return{element:"top",viewport:r};let[n="top",o="bottom"]=r.split(/\s+/).filter(Boolean);return{element:n,viewport:o}}function Te(e,r,n,o){switch(o){case"top":return e+n;case"center":return e+n+r/2;case"bottom":return e+n+r;default:return e+n}}function De(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 he(e){let r=e.tagName.toLowerCase();if(r==="rect"){let n=parseFloat(e.getAttribute("width")??"0"),o=parseFloat(e.getAttribute("height")??"0");return 2*(n+o)}if(r==="circle"){let n=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*n}return e.getTotalLength()}function _e(e,r,n){return Math.min(n,Math.max(r,e))}function G(e,r,n,o){return n===r?0:_e((e-r)/(n-r)*o,0,1)}function Ie(e,r,n,o,l){let c=Te(e.top,e.height,r,o.element)-De(o.viewport,n),u=Te(e.top,e.height,r,l.element)-De(l.viewport,n);return{tStart:c,tEnd:u}}function Me(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 o=/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i.exec(e);return o?[parseInt(o[1]),parseInt(o[2]),parseInt(o[3])]:null}function be(e,r,n){let o=Me(e),l=Me(r);return!o||!l?e:`rgb(${Math.round(o[0]+(l[0]-o[0])*n)},${Math.round(o[1]+(l[1]-o[1])*n)},${Math.round(o[2]+(l[2]-o[2])*n)})`}function Le(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r)}function je(e){let r=e.getAttribute("stroke"),n=e.getAttribute("fill");!r||r==="none"?Le("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&Le("Element has a fill \u2014 it may obscure the stroke animation.",e)}function Je(e,r,n){let o=document.createElement("div");o.setAttribute("data-svg-scroll-draw-debug",""),o.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 l(){let c=n==="x"?window.scrollX:window.scrollY,u=e-c,y=r-c,B=n==="x";o.innerHTML=`
2
+ <div style="position:absolute;${B?`left:${u}px;top:0;bottom:0;border-left:2px dashed #22c55e;`:`top:${u}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;${B?`left:${y}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${y}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",l,{passive:!0}),l(),o}function Oe(e,r,n){let o=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),l=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,c=>{let u=parseFloat(c),y=o[l++]??u;return String(+(u+(y-u)*n).toFixed(4))})}function ne(e,r={}){if(typeof window>"u")return{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};let n=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:o="path, polyline, line, polygon, rect, circle",speed:l=1,fade:c=!1,easing:u="linear",trigger:y={},stagger:B=0,direction:L="forward",once:X=!1,debug:Ce=!1,axis:E="y",scrollContainer:se,autoReverse:oe=!1,delay:ve=0,strokeColor:P,strokeWidth:N,fillOpacity:R,waypoints:ie,velocityScale:le=!1,threshold:Fe=0,rootMargin:Pe="0px",repeat:_=0,repeatDelay:xe=0,morphTo:O,clip:ae,onProgress:Ee,onStart:$e,onComplete:j}=r,W=ae===!0?"left":typeof ae=="string"?ae:!1,ce=typeof u=="function"?u:ye[u]??ye.linear,Ne=ge(y.start??"top bottom"),Re=ge(y.end??"bottom top"),d=typeof se=="string"?document.querySelector(se):se??null,k=Array.isArray(P)?P[0]:null,g=Array.isArray(P)?P[1]:typeof P=="string"?P:null,h=Array.isArray(N)?N[0]:null,b=Array.isArray(N)?N[1]:typeof N=="number"?N:null,w=Array.isArray(R)?R[0]:null,v=Array.isArray(R)?R[1]:typeof R=="number"?R:null;function V(t){let s=t*100;switch(W){case"right":return`inset(0 0 0 ${100-s}%)`;case"top":return`inset(0 0 ${100-s}% 0)`;case"bottom":return`inset(${100-s}% 0 0 0)`;case"center":return`circle(${t*150}% at 50% 50%)`;default:return`inset(0 ${100-s}% 0 0)`}}let H=W?[]:Array.from(e.querySelectorAll(o)),$=[],S=[],T=0,D=0,A=!1,C=!1,M=0,J=!1,x=-1,K=-1,F=!1,Q=0,q=0,U,ue=null,Y=new Set,Z=-1,Ae=performance.now();function fe(){return d?E==="x"?d.scrollLeft:d.scrollTop:E==="x"?window.scrollX:window.scrollY}function We(){return d?E==="x"?d.clientWidth:d.clientHeight:E==="x"?window.innerWidth:window.innerHeight}function ke(){let t=e.getBoundingClientRect(),s,a,m;if(d){let z=d.getBoundingClientRect();s=E==="x"?t.left-z.left+d.scrollLeft:t.top-z.top+d.scrollTop,a=E==="x"?t.width:t.height,m=fe()}else s=E==="x"?t.left:t.top,a=E==="x"?t.width:t.height,m=fe();let re=Ie({top:s,height:a},m,We(),Ne,Re);T=re.tStart,D=re.tEnd,Ce&&process.env.NODE_ENV!=="production"&&(ue?.remove(),ue=Je(T,D,E))}function Ve(t,s){if(W){let a=s==="reverse"?1-t:t;e.style.clipPath=V(a);return}H.forEach((a,m)=>{a.style.strokeDashoffset=s==="reverse"?`${$[m]*t}`:`${$[m]*(1-t)}`,c&&(a.style.opacity=s==="reverse"?`${1-t}`:`${t}`),k&&g?a.style.stroke=be(k,g,t):g&&(a.style.stroke=g),h!==null&&b!==null?a.style.strokeWidth=`${h+(b-h)*t}`:b!==null&&(a.style.strokeWidth=`${b}`),w!==null&&v!==null?a.style.fillOpacity=`${w+(v-w)*t}`:v!==null&&(a.style.fillOpacity=`${v}`),O&&a.tagName.toLowerCase()==="path"&&S[m]&&a.setAttribute("d",Oe(S[m],O,t))})}function Se(){if(W){e.style.clipPath=V(0);return}H.forEach((t,s)=>{t.style.strokeDasharray=`${$[s]}`,t.style.strokeDashoffset=L==="reverse"?"0":`${$[s]}`,c?t.style.opacity=L==="reverse"?"1":"0":t.style.opacity="",k&&(t.style.stroke=k),h!==null&&(t.style.strokeWidth=`${h}`),w!==null&&(t.style.fillOpacity=`${w}`),O&&t.tagName.toLowerCase()==="path"&&S[s]&&t.setAttribute("d",S[s])})}if(H.forEach(t=>{je(t);let s=he(t);$.push(s),t.tagName.toLowerCase()==="path"?S.push(t.getAttribute("d")??""):S.push(""),n?(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=L==="reverse"?`${s}`:"0",c&&(t.style.opacity="1"),g&&(t.style.stroke=g),b!==null&&(t.style.strokeWidth=`${b}`),v!==null&&(t.style.fillOpacity=`${v}`),O&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",O)):(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=L==="reverse"?"0":`${s}`,c?t.style.opacity=L==="reverse"?"1":"0":t.style.opacity="",k&&(t.style.stroke=k),h!==null&&(t.style.strokeWidth=`${h}`),w!==null&&(t.style.fillOpacity=`${w}`))}),W){if(n)return e.style.clipPath=V(1),j?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};e.style.clipPath=V(0)}else if(n)return j?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};ke();function ee(){if(!J||F)return;let t=performance.now(),s=fe(),a=l;if(le!==!1){let i=t-Ae,f=i>0?Math.abs(s-(Z<0?s:Z))/i:0;a=l*Math.max(.2,1+f*(typeof le=="number"?le:1)*.04)}Z=s,Ae=t;let m=oe?K===-1||s>=K?"forward":"reverse":L;K=s;let re=D-T,z=!0;if(W){let i=ce(G(s,T,D,a));X&&!oe&&(x=Math.max(x,i),i=x),Q=i;let f=m==="reverse"?1-i:i;e.style.clipPath=V(f),Ee?.(i),!C&&G(s,T,D,a)>0&&(C=!0,$e?.()),i>=1&&!A?(A=!0,j?.(),q<(_==="infinite"?1/0:_??0)&&(q++,U=setTimeout(()=>{x=-1,C=!1,A=!1,e.style.clipPath=V(0)},xe))):i<1&&!X&&(A=!1),M=requestAnimationFrame(ee);return}if(H.forEach((i,f)=>{let I=f*B*re,p=ce(G(s,T+I,D+I,a));X&&!oe&&(x=Math.max(x,p),p=x),Q=p,i.style.strokeDashoffset=m==="reverse"?`${$[f]*p}`:`${$[f]*(1-p)}`,c&&(i.style.opacity=m==="reverse"?`${1-p}`:`${p}`),k&&g?i.style.stroke=be(k,g,p):g&&(i.style.stroke=g),h!==null&&b!==null?i.style.strokeWidth=`${h+(b-h)*p}`:b!==null&&(i.style.strokeWidth=`${b}`),w!==null&&v!==null?i.style.fillOpacity=`${w+(v-w)*p}`:v!==null&&(i.style.fillOpacity=`${v}`),O&&i.tagName.toLowerCase()==="path"&&S[f]&&i.setAttribute("d",Oe(S[f],O,p)),f===0&&Ee?.(p),p<1&&(z=!1)}),ie){let i=ce(G(s,T,D,a));for(let f in ie){let I=parseFloat(f);i>=I&&!Y.has(I)&&(Y.add(I),ie[f]?.())}}!C&&G(s,T,D,a)>0&&(C=!0,$e?.()),z&&!A?(A=!0,j?.(),q<(_==="infinite"?1/0:_??0)&&(q++,U=setTimeout(()=>{x=-1,C=!1,A=!1,Y.clear(),Se()},xe))):!z&&!X&&(A=!1),M=requestAnimationFrame(ee)}let pe=new IntersectionObserver(t=>{t.forEach(s=>{J=s.isIntersecting,J&&!F?M=requestAnimationFrame(ee):cancelAnimationFrame(M)})},{root:d??null,threshold:Fe,rootMargin:Pe}),me;function te(){clearTimeout(me),me=setTimeout(()=>{H.forEach((t,s)=>{$[s]=he(t),t.style.strokeDasharray=`${$[s]}`}),ke()},150)}return window.addEventListener("resize",te),window.addEventListener("orientationchange",te),ve>0?setTimeout(()=>pe.observe(e),ve):pe.observe(e),{destroy(){cancelAnimationFrame(M),clearTimeout(U),pe.disconnect(),window.removeEventListener("resize",te),window.removeEventListener("orientationchange",te),clearTimeout(me),ue?.remove()},replay(){x=-1,K=-1,Z=-1,C=!1,A=!1,q=0,F=!1,Y.clear(),clearTimeout(U),Se()},pause(){F=!0,cancelAnimationFrame(M)},resume(){F&&(F=!1,J&&(M=requestAnimationFrame(ee)))},seek(t){let s=Math.min(1,Math.max(0,t));Q=s,x=s,F=!0,cancelAnimationFrame(M),Ve(s,L)},getProgress(){return Q}}}function Ke(e,r){let n={destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};if(typeof window>"u")return n;let o=typeof e=="string"?document.querySelector(e):e;return o?ne(o,r):(console.warn("[svg-scroll-draw] Container not found:",e),n)}var we=class extends HTMLElement{constructor(){super(...arguments);this.instance=null}connectedCallback(){let n={},o=this.getAttribute("speed"),l=this.getAttribute("easing"),c=this.getAttribute("stagger"),u=this.getAttribute("direction"),y=this.getAttribute("selector");o&&(n.speed=parseFloat(o)),l&&(n.easing=l),c&&(n.stagger=parseFloat(c)),u&&(n.direction=u),y&&(n.selector=y),this.hasAttribute("fade")&&(n.fade=this.getAttribute("fade")!=="false"),this.instance=ne(this,n)}disconnectedCallback(){this.instance?.destroy(),this.instance=null}};typeof customElements<"u"&&!customElements.get("scroll-draw")&&customElements.define("scroll-draw",we);return Xe(Qe);})();