svg-scroll-draw 0.5.0 → 0.6.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/dist/angular/index.cjs +3 -3
- package/dist/angular/index.d.mts +21 -1
- package/dist/angular/index.d.ts +21 -1
- package/dist/angular/index.mjs +3 -3
- package/dist/astro/index.cjs +3 -0
- package/dist/astro/index.d.mts +79 -0
- package/dist/astro/index.d.ts +79 -0
- package/dist/astro/index.mjs +3 -0
- package/dist/cdn/svg-scroll-draw.global.js +3 -3
- package/dist/group/index.cjs +3 -0
- package/dist/group/index.d.mts +89 -0
- package/dist/group/index.d.ts +89 -0
- package/dist/group/index.mjs +3 -0
- package/dist/index.cjs +3 -3
- package/dist/index.d.mts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.mjs +3 -3
- package/dist/nuxt/index.cjs +3 -0
- package/dist/nuxt/index.d.mts +166 -0
- package/dist/nuxt/index.d.ts +166 -0
- package/dist/nuxt/index.mjs +3 -0
- package/dist/react/index.cjs +3 -3
- package/dist/react/index.d.mts +13 -1
- package/dist/react/index.d.ts +13 -1
- package/dist/react/index.mjs +3 -3
- package/dist/solid/index.cjs +3 -3
- package/dist/solid/index.d.mts +21 -1
- package/dist/solid/index.d.ts +21 -1
- package/dist/solid/index.mjs +3 -3
- package/dist/svelte/index.cjs +3 -3
- package/dist/svelte/index.d.mts +21 -1
- package/dist/svelte/index.d.ts +21 -1
- package/dist/svelte/index.mjs +3 -3
- package/dist/vue/index.cjs +3 -3
- package/dist/vue/index.d.mts +13 -1
- package/dist/vue/index.d.ts +13 -1
- package/dist/vue/index.mjs +3 -3
- package/package.json +23 -2
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import * as vue from 'vue';
|
|
2
|
+
import { App } from 'vue';
|
|
3
|
+
|
|
4
|
+
type EasingName = 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'spring';
|
|
5
|
+
interface TriggerConfig {
|
|
6
|
+
start?: string;
|
|
7
|
+
end?: string;
|
|
8
|
+
}
|
|
9
|
+
interface ScrollDrawOptions {
|
|
10
|
+
selector?: string;
|
|
11
|
+
speed?: number;
|
|
12
|
+
fade?: boolean;
|
|
13
|
+
easing?: EasingName | ((t: number) => number);
|
|
14
|
+
trigger?: TriggerConfig;
|
|
15
|
+
stagger?: number;
|
|
16
|
+
direction?: 'forward' | 'reverse';
|
|
17
|
+
once?: boolean;
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
/** Scroll axis to track. 'y' (default) for vertical, 'x' for horizontal. */
|
|
20
|
+
axis?: 'x' | 'y';
|
|
21
|
+
/** CSS selector or Element for a custom scroll container (default: window). */
|
|
22
|
+
scrollContainer?: string | Element;
|
|
23
|
+
/** Automatically reverse the animation when the user scrolls back up. */
|
|
24
|
+
autoReverse?: boolean;
|
|
25
|
+
/** Delay in milliseconds before the engine starts observing. */
|
|
26
|
+
delay?: number;
|
|
27
|
+
/** Animate stroke color. Single string = static override. Tuple = interpolate from → to. */
|
|
28
|
+
strokeColor?: string | [string, string];
|
|
29
|
+
/** Animate stroke width. Single number = static override. Tuple = interpolate from → to. */
|
|
30
|
+
strokeWidth?: number | [number, number];
|
|
31
|
+
/** Fire callbacks at specific progress thresholds (0–1). Resets on replay(). */
|
|
32
|
+
waypoints?: Record<number, () => void>;
|
|
33
|
+
/** Scale animation speed by scroll velocity — faster scrolling = faster draw. Pass a number to control sensitivity (default 1). */
|
|
34
|
+
velocityScale?: boolean | number;
|
|
35
|
+
/** IntersectionObserver threshold (0–1). Default 0. */
|
|
36
|
+
threshold?: number;
|
|
37
|
+
/** IntersectionObserver rootMargin. Default "0px". */
|
|
38
|
+
rootMargin?: string;
|
|
39
|
+
/** Repeat the animation N times after completion. Use 'infinite' to loop forever. */
|
|
40
|
+
repeat?: number | 'infinite';
|
|
41
|
+
/** Milliseconds to wait between repeats. Default 0. */
|
|
42
|
+
repeatDelay?: number;
|
|
43
|
+
/** Target path `d` attribute to morph toward as the animation progresses. Paths must have compatible structures. */
|
|
44
|
+
morphTo?: string;
|
|
45
|
+
onProgress?: (alpha: number) => void;
|
|
46
|
+
onStart?: () => void;
|
|
47
|
+
onComplete?: () => void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Composable — attach to any container ref. */
|
|
51
|
+
declare function useScrollDraw(options?: ScrollDrawOptions): vue.Ref<HTMLElement | null, HTMLElement | null>;
|
|
52
|
+
/** Component — wraps children in a <div> and initialises the engine. */
|
|
53
|
+
declare const ScrollDraw: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
54
|
+
selector: {
|
|
55
|
+
type: StringConstructor;
|
|
56
|
+
};
|
|
57
|
+
speed: {
|
|
58
|
+
type: NumberConstructor;
|
|
59
|
+
};
|
|
60
|
+
fade: {
|
|
61
|
+
type: BooleanConstructor;
|
|
62
|
+
};
|
|
63
|
+
stagger: {
|
|
64
|
+
type: NumberConstructor;
|
|
65
|
+
};
|
|
66
|
+
easing: {
|
|
67
|
+
type: (StringConstructor | FunctionConstructor)[];
|
|
68
|
+
};
|
|
69
|
+
direction: {
|
|
70
|
+
type: () => "forward" | "reverse";
|
|
71
|
+
};
|
|
72
|
+
trigger: {
|
|
73
|
+
type: ObjectConstructor;
|
|
74
|
+
};
|
|
75
|
+
onProgress: {
|
|
76
|
+
type: FunctionConstructor;
|
|
77
|
+
};
|
|
78
|
+
onStart: {
|
|
79
|
+
type: FunctionConstructor;
|
|
80
|
+
};
|
|
81
|
+
onComplete: {
|
|
82
|
+
type: FunctionConstructor;
|
|
83
|
+
};
|
|
84
|
+
once: {
|
|
85
|
+
type: BooleanConstructor;
|
|
86
|
+
};
|
|
87
|
+
debug: {
|
|
88
|
+
type: BooleanConstructor;
|
|
89
|
+
};
|
|
90
|
+
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
91
|
+
[key: string]: any;
|
|
92
|
+
}>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
93
|
+
selector: {
|
|
94
|
+
type: StringConstructor;
|
|
95
|
+
};
|
|
96
|
+
speed: {
|
|
97
|
+
type: NumberConstructor;
|
|
98
|
+
};
|
|
99
|
+
fade: {
|
|
100
|
+
type: BooleanConstructor;
|
|
101
|
+
};
|
|
102
|
+
stagger: {
|
|
103
|
+
type: NumberConstructor;
|
|
104
|
+
};
|
|
105
|
+
easing: {
|
|
106
|
+
type: (StringConstructor | FunctionConstructor)[];
|
|
107
|
+
};
|
|
108
|
+
direction: {
|
|
109
|
+
type: () => "forward" | "reverse";
|
|
110
|
+
};
|
|
111
|
+
trigger: {
|
|
112
|
+
type: ObjectConstructor;
|
|
113
|
+
};
|
|
114
|
+
onProgress: {
|
|
115
|
+
type: FunctionConstructor;
|
|
116
|
+
};
|
|
117
|
+
onStart: {
|
|
118
|
+
type: FunctionConstructor;
|
|
119
|
+
};
|
|
120
|
+
onComplete: {
|
|
121
|
+
type: FunctionConstructor;
|
|
122
|
+
};
|
|
123
|
+
once: {
|
|
124
|
+
type: BooleanConstructor;
|
|
125
|
+
};
|
|
126
|
+
debug: {
|
|
127
|
+
type: BooleanConstructor;
|
|
128
|
+
};
|
|
129
|
+
}>> & Readonly<{}>, {
|
|
130
|
+
fade: boolean;
|
|
131
|
+
once: boolean;
|
|
132
|
+
debug: boolean;
|
|
133
|
+
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Nuxt 3 integration for svg-scroll-draw.
|
|
137
|
+
*
|
|
138
|
+
* Re-exports the Vue composable and component for direct use, plus a
|
|
139
|
+
* plugin factory for global auto-registration.
|
|
140
|
+
*
|
|
141
|
+
* ## Option A — Import per component (recommended)
|
|
142
|
+
* ```ts
|
|
143
|
+
* import { useScrollDraw, ScrollDraw } from 'svg-scroll-draw/nuxt';
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* ## Option B — Global auto-registration via Nuxt plugin
|
|
147
|
+
* Create `plugins/svg-scroll-draw.ts` in your Nuxt project:
|
|
148
|
+
* ```ts
|
|
149
|
+
* import { createScrollDrawPlugin } from 'svg-scroll-draw/nuxt';
|
|
150
|
+
* export default defineNuxtPlugin((nuxtApp) => {
|
|
151
|
+
* nuxtApp.vueApp.use(createScrollDrawPlugin());
|
|
152
|
+
* });
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
* Then use <ScrollDraw> globally with no imports.
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Vue plugin that globally registers the <ScrollDraw> component.
|
|
160
|
+
* Pass to nuxtApp.vueApp.use() inside a Nuxt plugin.
|
|
161
|
+
*/
|
|
162
|
+
declare function createScrollDrawPlugin(): {
|
|
163
|
+
install(app: App): void;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export { ScrollDraw, type ScrollDrawOptions, createScrollDrawPlugin, useScrollDraw };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {defineComponent,ref,onMounted,onUnmounted,h}from'vue';var re={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 ne(e="top bottom"){let r=e.trim();if(/^\d+(\.\d+)?%$/.test(r))return {element:"top",viewport:r};let[o="top",n="bottom"]=r.split(/\s+/).filter(Boolean);return {element:o,viewport:n}}function be(e,r,o,n){switch(n){case "top":return e+o;case "center":return e+o+r/2;case "bottom":return e+o+r;default:return e+o}}function he(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 oe(e){let r=e.tagName.toLowerCase();if(r==="rect"){let o=parseFloat(e.getAttribute("width")??"0"),n=parseFloat(e.getAttribute("height")??"0");return 2*(o+n)}if(r==="circle"){let o=parseFloat(e.getAttribute("r")??"0");return 2*Math.PI*o}return e.getTotalLength()}function Ne(e,r,o){return Math.min(o,Math.max(r,e))}function H(e,r,o,n){return o===r?0:Ne((e-r)/(o-r)*n,0,1)}function ve(e,r,o,n,i){let c=be(e.top,e.height,r,n.element)-he(n.viewport,o),u=be(e.top,e.height,r,i.element)-he(i.viewport,o);return {tStart:c,tEnd:u}}function we(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 o=/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(o)return [parseInt(o[1],16),parseInt(o[2],16),parseInt(o[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 se(e,r,o){let n=we(e),i=we(r);return !n||!i?e:`rgb(${Math.round(n[0]+(i[0]-n[0])*o)},${Math.round(n[1]+(i[1]-n[1])*o)},${Math.round(n[2]+(i[2]-n[2])*o)})`}function xe(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}function Re(e){let r=e.getAttribute("stroke"),o=e.getAttribute("fill");!r||r==="none"?xe("Element has no stroke \u2014 path will not be visible.",e):o&&o!=="none"&&o!=="transparent"&&xe("Element has a fill \u2014 it may obscure the stroke animation.",e);}function We(e,r,o){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 i(){let c=o==="x"?window.scrollX:window.scrollY,u=e-c,S=r-c,N=o==="x";n.innerHTML=`
|
|
2
|
+
<div style="position:absolute;${N?`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;${N?`left:${S}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${S}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",i,{passive:true}),i(),n}function Se(e,r,o){let n=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),i=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,c=>{let u=parseFloat(c),S=n[i++]??u;return String(+(u+(S-u)*o).toFixed(4))})}function ie(e,r={}){if(typeof window>"u")return {destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>0};let o=window.matchMedia("(prefers-reduced-motion: reduce)").matches,{selector:n="path, polyline, line, polygon, rect, circle",speed:i=1,fade:c=false,easing:u="linear",trigger:S={},stagger:N=0,direction:E="forward",once:le=false,debug:ke=false,axis:h="y",scrollContainer:X,autoReverse:ce=false,delay:ue=0,strokeColor:T,strokeWidth:C,waypoints:_,velocityScale:j=false,threshold:$e=0,rootMargin:Te="0px",repeat:fe=0,repeatDelay:Ce=0,morphTo:A,onProgress:Me,onStart:Fe,onComplete:me}=r,de=typeof u=="function"?u:re[u]??re.linear,Le=ne(S.start??"top bottom"),Ie=ne(S.end??"bottom top"),m=typeof X=="string"?document.querySelector(X):X??null,v=Array.isArray(T)?T[0]:null,g=Array.isArray(T)?T[1]:typeof T=="string"?T:null,y=Array.isArray(C)?C[0]:null,b=Array.isArray(C)?C[1]:typeof C=="number"?C:null,O=Array.from(e.querySelectorAll(n)),w=[],x=[],M=0,F=0,P=false,R=false,D=0,W=false,L=-1,V=-1,k=false,U=0,J=0,K,Q=null,z=new Set,G=-1,pe=performance.now();function Y(){return m?h==="x"?m.scrollLeft:m.scrollTop:h==="x"?window.scrollX:window.scrollY}function Oe(){return m?h==="x"?m.clientWidth:m.clientHeight:h==="x"?window.innerWidth:window.innerHeight}function ge(){let t=e.getBoundingClientRect(),s,a,d;if(m){let I=m.getBoundingClientRect();s=h==="x"?t.left-I.left+m.scrollLeft:t.top-I.top+m.scrollTop,a=h==="x"?t.width:t.height,d=Y();}else s=h==="x"?t.left:t.top,a=h==="x"?t.width:t.height,d=Y();let q=ve({top:s,height:a},d,Oe(),Le,Ie);M=q.tStart,F=q.tEnd,ke&&process.env.NODE_ENV!=="production"&&(Q?.remove(),Q=We(M,F,h));}function Pe(t,s){O.forEach((a,d)=>{a.style.strokeDashoffset=s==="reverse"?`${w[d]*t}`:`${w[d]*(1-t)}`,c&&(a.style.opacity=s==="reverse"?`${1-t}`:`${t}`),v&&g?a.style.stroke=se(v,g,t):g&&(a.style.stroke=g),y!==null&&b!==null?a.style.strokeWidth=`${y+(b-y)*t}`:b!==null&&(a.style.strokeWidth=`${b}`),A&&a.tagName.toLowerCase()==="path"&&x[d]&&a.setAttribute("d",Se(x[d],A,t));});}function ye(){O.forEach((t,s)=>{t.style.strokeDasharray=`${w[s]}`,t.style.strokeDashoffset=E==="reverse"?"0":`${w[s]}`,c?t.style.opacity=E==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`),A&&t.tagName.toLowerCase()==="path"&&x[s]&&t.setAttribute("d",x[s]);});}if(O.forEach(t=>{Re(t);let s=oe(t);w.push(s),t.tagName.toLowerCase()==="path"?x.push(t.getAttribute("d")??""):x.push(""),o?(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=E==="reverse"?`${s}`:"0",c&&(t.style.opacity="1"),g&&(t.style.stroke=g),b!==null&&(t.style.strokeWidth=`${b}`),A&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",A)):(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=E==="reverse"?"0":`${s}`,c?t.style.opacity=E==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`));}),o)return me?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};ge();function Z(){if(!W||k)return;let t=performance.now(),s=Y(),a=i;if(j!==false){let l=t-pe,p=l>0?Math.abs(s-(G<0?s:G))/l:0;a=i*Math.max(.2,1+p*(typeof j=="number"?j:1)*.04);}G=s,pe=t;let d=ce?V===-1||s>=V?"forward":"reverse":E;V=s;let q=F-M,I=true;if(O.forEach((l,p)=>{let $=p*N*q,f=de(H(s,M+$,F+$,a));le&&!ce&&(L=Math.max(L,f),f=L),U=f,l.style.strokeDashoffset=d==="reverse"?`${w[p]*f}`:`${w[p]*(1-f)}`,c&&(l.style.opacity=d==="reverse"?`${1-f}`:`${f}`),v&&g?l.style.stroke=se(v,g,f):g&&(l.style.stroke=g),y!==null&&b!==null?l.style.strokeWidth=`${y+(b-y)*f}`:b!==null&&(l.style.strokeWidth=`${b}`),A&&l.tagName.toLowerCase()==="path"&&x[p]&&l.setAttribute("d",Se(x[p],A,f)),p===0&&Me?.(f),f<1&&(I=false);}),_){let l=de(H(s,M,F,a));for(let p in _){let $=parseFloat(p);l>=$&&!z.has($)&&(z.add($),_[p]?.());}}!R&&H(s,M,F,a)>0&&(R=true,Fe?.()),I&&!P?(P=true,me?.(),J<(fe==="infinite"?1/0:fe??0)&&(J++,K=setTimeout(()=>{L=-1,R=false,P=false,z.clear(),ye();},Ce))):!I&&!le&&(P=false),D=requestAnimationFrame(Z);}let ee=new IntersectionObserver(t=>{t.forEach(s=>{W=s.isIntersecting,W&&!k?D=requestAnimationFrame(Z):cancelAnimationFrame(D);});},{root:m??null,threshold:$e,rootMargin:Te}),te;function B(){clearTimeout(te),te=setTimeout(()=>{O.forEach((t,s)=>{w[s]=oe(t),t.style.strokeDasharray=`${w[s]}`;}),ge();},150);}return window.addEventListener("resize",B),window.addEventListener("orientationchange",B),ue>0?setTimeout(()=>ee.observe(e),ue):ee.observe(e),{destroy(){cancelAnimationFrame(D),clearTimeout(K),ee.disconnect(),window.removeEventListener("resize",B),window.removeEventListener("orientationchange",B),clearTimeout(te),Q?.remove();},replay(){L=-1,V=-1,G=-1,R=false,P=false,J=0,k=false,z.clear(),clearTimeout(K),ye();},pause(){k=true,cancelAnimationFrame(D);},resume(){k&&(k=false,W&&(D=requestAnimationFrame(Z)));},seek(t){let s=Math.min(1,Math.max(0,t));U=s,L=s,k=true,cancelAnimationFrame(D),Pe(s,E);},getProgress(){return U}}}function Ge(e={}){let r=ref(null);return onMounted(()=>{if(!r.value)return;let o=ie(r.value,e);onUnmounted(()=>o.destroy());}),r}var ae=defineComponent({name:"ScrollDraw",props:{selector:{type:String},speed:{type:Number},fade:{type:Boolean},stagger:{type:Number},easing:{type:[String,Function]},direction:{type:String},trigger:{type:Object},onProgress:{type:Function},onStart:{type:Function},onComplete:{type:Function},once:{type:Boolean},debug:{type:Boolean}},setup(e,{slots:r}){let o=ref(null);return onMounted(()=>{if(!o.value)return;let n={};e.selector!=null&&(n.selector=e.selector),e.speed!=null&&(n.speed=e.speed),e.fade!=null&&(n.fade=e.fade),e.stagger!=null&&(n.stagger=e.stagger),e.easing!=null&&(n.easing=e.easing),e.direction!=null&&(n.direction=e.direction),e.trigger!=null&&(n.trigger=e.trigger),e.once!=null&&(n.once=e.once),e.debug!=null&&(n.debug=e.debug),e.onProgress!=null&&(n.onProgress=e.onProgress),e.onStart!=null&&(n.onStart=e.onStart),e.onComplete!=null&&(n.onComplete=e.onComplete);let i=ie(o.value,n);onUnmounted(()=>i.destroy());}),()=>h("div",{ref:o},r.default?.())}});function Je(){return {install(e){e.component("ScrollDraw",ae);}}}export{ae as ScrollDraw,Je as createScrollDrawPlugin,Ge as useScrollDraw};
|
package/dist/react/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var
|
|
2
|
-
<div style="position:absolute;${
|
|
3
|
-
<div style="position:absolute;${
|
|
1
|
+
'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var re={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 ne(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 ge(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 ye(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 oe(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 Ce(e,r,n){return Math.min(n,Math.max(r,e))}function H(e,r,n,o){return n===r?0:Ce((e-r)/(n-r)*o,0,1)}function be(e,r,n,o,i){let l=ge(e.top,e.height,r,o.element)-ye(o.viewport,n),u=ge(e.top,e.height,r,i.element)-ye(i.viewport,n);return {tStart:l,tEnd:u}}function he(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 se(e,r,n){let o=he(e),i=he(r);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 we(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}function Fe(e){let r=e.getAttribute("stroke"),n=e.getAttribute("fill");!r||r==="none"?we("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&we("Element has a fill \u2014 it may obscure the stroke animation.",e);}function Ne(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 i(){let l=n==="x"?window.scrollX:window.scrollY,u=e-l,E=r-l,P=n==="x";o.innerHTML=`
|
|
2
|
+
<div style="position:absolute;${P?`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;${P?`left:${E}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${E}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 ve(e,r,n){let o=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),i=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,l=>{let u=parseFloat(l),E=o[i++]??u;return String(+(u+(E-u)*n).toFixed(4))})}function xe(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:i=1,fade:l=false,easing:u="linear",trigger:E={},stagger:P=0,direction:k="forward",once:ie=false,debug:Ee=false,axis:b="y",scrollContainer:X,autoReverse:ae=false,delay:le=0,strokeColor:D,strokeWidth:L,waypoints:_,velocityScale:J=false,threshold:ke=0,rootMargin:$e="0px",repeat:ce=0,repeatDelay:Ae=0,morphTo:$,onProgress:Se,onStart:Te,onComplete:ue}=r,fe=typeof u=="function"?u:re[u]??re.linear,De=ne(E.start??"top bottom"),Le=ne(E.end??"bottom top"),p=typeof X=="string"?document.querySelector(X):X??null,v=Array.isArray(D)?D[0]:null,g=Array.isArray(D)?D[1]:typeof D=="string"?D:null,y=Array.isArray(L)?L[0]:null,h=Array.isArray(L)?L[1]:typeof L=="number"?L:null,N=Array.from(e.querySelectorAll(o)),w=[],x=[],M=0,I=0,R=false,W=false,A=0,V=false,C=-1,z=-1,S=false,K=0,Q=0,U,Y=null,O=new Set,G=-1,pe=performance.now();function Z(){return p?b==="x"?p.scrollLeft:p.scrollTop:b==="x"?window.scrollX:window.scrollY}function Me(){return p?b==="x"?p.clientWidth:p.clientHeight:b==="x"?window.innerWidth:window.innerHeight}function me(){let t=e.getBoundingClientRect(),s,a,m;if(p){let F=p.getBoundingClientRect();s=b==="x"?t.left-F.left+p.scrollLeft:t.top-F.top+p.scrollTop,a=b==="x"?t.width:t.height,m=Z();}else s=b==="x"?t.left:t.top,a=b==="x"?t.width:t.height,m=Z();let B=be({top:s,height:a},m,Me(),De,Le);M=B.tStart,I=B.tEnd,Ee&&process.env.NODE_ENV!=="production"&&(Y?.remove(),Y=Ne(M,I,b));}function Ie(t,s){N.forEach((a,m)=>{a.style.strokeDashoffset=s==="reverse"?`${w[m]*t}`:`${w[m]*(1-t)}`,l&&(a.style.opacity=s==="reverse"?`${1-t}`:`${t}`),v&&g?a.style.stroke=se(v,g,t):g&&(a.style.stroke=g),y!==null&&h!==null?a.style.strokeWidth=`${y+(h-y)*t}`:h!==null&&(a.style.strokeWidth=`${h}`),$&&a.tagName.toLowerCase()==="path"&&x[m]&&a.setAttribute("d",ve(x[m],$,t));});}function de(){N.forEach((t,s)=>{t.style.strokeDasharray=`${w[s]}`,t.style.strokeDashoffset=k==="reverse"?"0":`${w[s]}`,l?t.style.opacity=k==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`),$&&t.tagName.toLowerCase()==="path"&&x[s]&&t.setAttribute("d",x[s]);});}if(N.forEach(t=>{Fe(t);let s=oe(t);w.push(s),t.tagName.toLowerCase()==="path"?x.push(t.getAttribute("d")??""):x.push(""),n?(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=k==="reverse"?`${s}`:"0",l&&(t.style.opacity="1"),g&&(t.style.stroke=g),h!==null&&(t.style.strokeWidth=`${h}`),$&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",$)):(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=k==="reverse"?"0":`${s}`,l?t.style.opacity=k==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`));}),n)return ue?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};me();function j(){if(!V||S)return;let t=performance.now(),s=Z(),a=i;if(J!==false){let c=t-pe,d=c>0?Math.abs(s-(G<0?s:G))/c:0;a=i*Math.max(.2,1+d*(typeof J=="number"?J:1)*.04);}G=s,pe=t;let m=ae?z===-1||s>=z?"forward":"reverse":k;z=s;let B=I-M,F=true;if(N.forEach((c,d)=>{let T=d*P*B,f=fe(H(s,M+T,I+T,a));ie&&!ae&&(C=Math.max(C,f),f=C),K=f,c.style.strokeDashoffset=m==="reverse"?`${w[d]*f}`:`${w[d]*(1-f)}`,l&&(c.style.opacity=m==="reverse"?`${1-f}`:`${f}`),v&&g?c.style.stroke=se(v,g,f):g&&(c.style.stroke=g),y!==null&&h!==null?c.style.strokeWidth=`${y+(h-y)*f}`:h!==null&&(c.style.strokeWidth=`${h}`),$&&c.tagName.toLowerCase()==="path"&&x[d]&&c.setAttribute("d",ve(x[d],$,f)),d===0&&Se?.(f),f<1&&(F=false);}),_){let c=fe(H(s,M,I,a));for(let d in _){let T=parseFloat(d);c>=T&&!O.has(T)&&(O.add(T),_[d]?.());}}!W&&H(s,M,I,a)>0&&(W=true,Te?.()),F&&!R?(R=true,ue?.(),Q<(ce==="infinite"?1/0:ce??0)&&(Q++,U=setTimeout(()=>{C=-1,W=false,R=false,O.clear(),de();},Ae))):!F&&!ie&&(R=false),A=requestAnimationFrame(j);}let ee=new IntersectionObserver(t=>{t.forEach(s=>{V=s.isIntersecting,V&&!S?A=requestAnimationFrame(j):cancelAnimationFrame(A);});},{root:p??null,threshold:ke,rootMargin:$e}),te;function q(){clearTimeout(te),te=setTimeout(()=>{N.forEach((t,s)=>{w[s]=oe(t),t.style.strokeDasharray=`${w[s]}`;}),me();},150);}return window.addEventListener("resize",q),window.addEventListener("orientationchange",q),le>0?setTimeout(()=>ee.observe(e),le):ee.observe(e),{destroy(){cancelAnimationFrame(A),clearTimeout(U),ee.disconnect(),window.removeEventListener("resize",q),window.removeEventListener("orientationchange",q),clearTimeout(te),Y?.remove();},replay(){C=-1,z=-1,G=-1,W=false,R=false,Q=0,S=false,O.clear(),clearTimeout(U),de();},pause(){S=true,cancelAnimationFrame(A);},resume(){S&&(S=false,V&&(A=requestAnimationFrame(j)));},seek(t){let s=Math.min(1,Math.max(0,t));K=s,C=s,S=true,cancelAnimationFrame(A),Ie(s,k);},getProgress(){return K}}}function He({children:e,className:r,style:n,...o}){let i=react.useRef(null);return react.useEffect(()=>{if(!i.current)return;let l=xe(i.current,o);return ()=>l.destroy()},[]),jsxRuntime.jsx("div",{ref:i,className:r,style:n,children:e})}exports.ScrollDraw=He;
|
package/dist/react/index.d.mts
CHANGED
|
@@ -22,7 +22,7 @@ interface ScrollDrawOptions {
|
|
|
22
22
|
scrollContainer?: string | Element;
|
|
23
23
|
/** Automatically reverse the animation when the user scrolls back up. */
|
|
24
24
|
autoReverse?: boolean;
|
|
25
|
-
/** Delay in milliseconds before the engine starts observing
|
|
25
|
+
/** Delay in milliseconds before the engine starts observing. */
|
|
26
26
|
delay?: number;
|
|
27
27
|
/** Animate stroke color. Single string = static override. Tuple = interpolate from → to. */
|
|
28
28
|
strokeColor?: string | [string, string];
|
|
@@ -30,6 +30,18 @@ interface ScrollDrawOptions {
|
|
|
30
30
|
strokeWidth?: number | [number, number];
|
|
31
31
|
/** Fire callbacks at specific progress thresholds (0–1). Resets on replay(). */
|
|
32
32
|
waypoints?: Record<number, () => void>;
|
|
33
|
+
/** Scale animation speed by scroll velocity — faster scrolling = faster draw. Pass a number to control sensitivity (default 1). */
|
|
34
|
+
velocityScale?: boolean | number;
|
|
35
|
+
/** IntersectionObserver threshold (0–1). Default 0. */
|
|
36
|
+
threshold?: number;
|
|
37
|
+
/** IntersectionObserver rootMargin. Default "0px". */
|
|
38
|
+
rootMargin?: string;
|
|
39
|
+
/** Repeat the animation N times after completion. Use 'infinite' to loop forever. */
|
|
40
|
+
repeat?: number | 'infinite';
|
|
41
|
+
/** Milliseconds to wait between repeats. Default 0. */
|
|
42
|
+
repeatDelay?: number;
|
|
43
|
+
/** Target path `d` attribute to morph toward as the animation progresses. Paths must have compatible structures. */
|
|
44
|
+
morphTo?: string;
|
|
33
45
|
onProgress?: (alpha: number) => void;
|
|
34
46
|
onStart?: () => void;
|
|
35
47
|
onComplete?: () => void;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ interface ScrollDrawOptions {
|
|
|
22
22
|
scrollContainer?: string | Element;
|
|
23
23
|
/** Automatically reverse the animation when the user scrolls back up. */
|
|
24
24
|
autoReverse?: boolean;
|
|
25
|
-
/** Delay in milliseconds before the engine starts observing
|
|
25
|
+
/** Delay in milliseconds before the engine starts observing. */
|
|
26
26
|
delay?: number;
|
|
27
27
|
/** Animate stroke color. Single string = static override. Tuple = interpolate from → to. */
|
|
28
28
|
strokeColor?: string | [string, string];
|
|
@@ -30,6 +30,18 @@ interface ScrollDrawOptions {
|
|
|
30
30
|
strokeWidth?: number | [number, number];
|
|
31
31
|
/** Fire callbacks at specific progress thresholds (0–1). Resets on replay(). */
|
|
32
32
|
waypoints?: Record<number, () => void>;
|
|
33
|
+
/** Scale animation speed by scroll velocity — faster scrolling = faster draw. Pass a number to control sensitivity (default 1). */
|
|
34
|
+
velocityScale?: boolean | number;
|
|
35
|
+
/** IntersectionObserver threshold (0–1). Default 0. */
|
|
36
|
+
threshold?: number;
|
|
37
|
+
/** IntersectionObserver rootMargin. Default "0px". */
|
|
38
|
+
rootMargin?: string;
|
|
39
|
+
/** Repeat the animation N times after completion. Use 'infinite' to loop forever. */
|
|
40
|
+
repeat?: number | 'infinite';
|
|
41
|
+
/** Milliseconds to wait between repeats. Default 0. */
|
|
42
|
+
repeatDelay?: number;
|
|
43
|
+
/** Target path `d` attribute to morph toward as the animation progresses. Paths must have compatible structures. */
|
|
44
|
+
morphTo?: string;
|
|
33
45
|
onProgress?: (alpha: number) => void;
|
|
34
46
|
onStart?: () => void;
|
|
35
47
|
onComplete?: () => void;
|
package/dist/react/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {useRef,useEffect}from'react';import {jsx}from'react/jsx-runtime';var
|
|
2
|
-
<div style="position:absolute;${
|
|
3
|
-
<div style="position:absolute;${
|
|
1
|
+
import {useRef,useEffect}from'react';import {jsx}from'react/jsx-runtime';var re={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 ne(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 ge(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 ye(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 oe(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 Ce(e,r,n){return Math.min(n,Math.max(r,e))}function H(e,r,n,o){return n===r?0:Ce((e-r)/(n-r)*o,0,1)}function be(e,r,n,o,i){let l=ge(e.top,e.height,r,o.element)-ye(o.viewport,n),u=ge(e.top,e.height,r,i.element)-ye(i.viewport,n);return {tStart:l,tEnd:u}}function he(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 se(e,r,n){let o=he(e),i=he(r);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 we(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}function Fe(e){let r=e.getAttribute("stroke"),n=e.getAttribute("fill");!r||r==="none"?we("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&we("Element has a fill \u2014 it may obscure the stroke animation.",e);}function Ne(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 i(){let l=n==="x"?window.scrollX:window.scrollY,u=e-l,E=r-l,P=n==="x";o.innerHTML=`
|
|
2
|
+
<div style="position:absolute;${P?`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;${P?`left:${E}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${E}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 ve(e,r,n){let o=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),i=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,l=>{let u=parseFloat(l),E=o[i++]??u;return String(+(u+(E-u)*n).toFixed(4))})}function xe(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:i=1,fade:l=false,easing:u="linear",trigger:E={},stagger:P=0,direction:k="forward",once:ie=false,debug:Ee=false,axis:b="y",scrollContainer:X,autoReverse:ae=false,delay:le=0,strokeColor:D,strokeWidth:L,waypoints:_,velocityScale:J=false,threshold:ke=0,rootMargin:$e="0px",repeat:ce=0,repeatDelay:Ae=0,morphTo:$,onProgress:Se,onStart:Te,onComplete:ue}=r,fe=typeof u=="function"?u:re[u]??re.linear,De=ne(E.start??"top bottom"),Le=ne(E.end??"bottom top"),p=typeof X=="string"?document.querySelector(X):X??null,v=Array.isArray(D)?D[0]:null,g=Array.isArray(D)?D[1]:typeof D=="string"?D:null,y=Array.isArray(L)?L[0]:null,h=Array.isArray(L)?L[1]:typeof L=="number"?L:null,N=Array.from(e.querySelectorAll(o)),w=[],x=[],M=0,I=0,R=false,W=false,A=0,V=false,C=-1,z=-1,S=false,K=0,Q=0,U,Y=null,O=new Set,G=-1,pe=performance.now();function Z(){return p?b==="x"?p.scrollLeft:p.scrollTop:b==="x"?window.scrollX:window.scrollY}function Me(){return p?b==="x"?p.clientWidth:p.clientHeight:b==="x"?window.innerWidth:window.innerHeight}function me(){let t=e.getBoundingClientRect(),s,a,m;if(p){let F=p.getBoundingClientRect();s=b==="x"?t.left-F.left+p.scrollLeft:t.top-F.top+p.scrollTop,a=b==="x"?t.width:t.height,m=Z();}else s=b==="x"?t.left:t.top,a=b==="x"?t.width:t.height,m=Z();let B=be({top:s,height:a},m,Me(),De,Le);M=B.tStart,I=B.tEnd,Ee&&process.env.NODE_ENV!=="production"&&(Y?.remove(),Y=Ne(M,I,b));}function Ie(t,s){N.forEach((a,m)=>{a.style.strokeDashoffset=s==="reverse"?`${w[m]*t}`:`${w[m]*(1-t)}`,l&&(a.style.opacity=s==="reverse"?`${1-t}`:`${t}`),v&&g?a.style.stroke=se(v,g,t):g&&(a.style.stroke=g),y!==null&&h!==null?a.style.strokeWidth=`${y+(h-y)*t}`:h!==null&&(a.style.strokeWidth=`${h}`),$&&a.tagName.toLowerCase()==="path"&&x[m]&&a.setAttribute("d",ve(x[m],$,t));});}function de(){N.forEach((t,s)=>{t.style.strokeDasharray=`${w[s]}`,t.style.strokeDashoffset=k==="reverse"?"0":`${w[s]}`,l?t.style.opacity=k==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`),$&&t.tagName.toLowerCase()==="path"&&x[s]&&t.setAttribute("d",x[s]);});}if(N.forEach(t=>{Fe(t);let s=oe(t);w.push(s),t.tagName.toLowerCase()==="path"?x.push(t.getAttribute("d")??""):x.push(""),n?(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=k==="reverse"?`${s}`:"0",l&&(t.style.opacity="1"),g&&(t.style.stroke=g),h!==null&&(t.style.strokeWidth=`${h}`),$&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",$)):(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=k==="reverse"?"0":`${s}`,l?t.style.opacity=k==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`));}),n)return ue?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};me();function j(){if(!V||S)return;let t=performance.now(),s=Z(),a=i;if(J!==false){let c=t-pe,d=c>0?Math.abs(s-(G<0?s:G))/c:0;a=i*Math.max(.2,1+d*(typeof J=="number"?J:1)*.04);}G=s,pe=t;let m=ae?z===-1||s>=z?"forward":"reverse":k;z=s;let B=I-M,F=true;if(N.forEach((c,d)=>{let T=d*P*B,f=fe(H(s,M+T,I+T,a));ie&&!ae&&(C=Math.max(C,f),f=C),K=f,c.style.strokeDashoffset=m==="reverse"?`${w[d]*f}`:`${w[d]*(1-f)}`,l&&(c.style.opacity=m==="reverse"?`${1-f}`:`${f}`),v&&g?c.style.stroke=se(v,g,f):g&&(c.style.stroke=g),y!==null&&h!==null?c.style.strokeWidth=`${y+(h-y)*f}`:h!==null&&(c.style.strokeWidth=`${h}`),$&&c.tagName.toLowerCase()==="path"&&x[d]&&c.setAttribute("d",ve(x[d],$,f)),d===0&&Se?.(f),f<1&&(F=false);}),_){let c=fe(H(s,M,I,a));for(let d in _){let T=parseFloat(d);c>=T&&!O.has(T)&&(O.add(T),_[d]?.());}}!W&&H(s,M,I,a)>0&&(W=true,Te?.()),F&&!R?(R=true,ue?.(),Q<(ce==="infinite"?1/0:ce??0)&&(Q++,U=setTimeout(()=>{C=-1,W=false,R=false,O.clear(),de();},Ae))):!F&&!ie&&(R=false),A=requestAnimationFrame(j);}let ee=new IntersectionObserver(t=>{t.forEach(s=>{V=s.isIntersecting,V&&!S?A=requestAnimationFrame(j):cancelAnimationFrame(A);});},{root:p??null,threshold:ke,rootMargin:$e}),te;function q(){clearTimeout(te),te=setTimeout(()=>{N.forEach((t,s)=>{w[s]=oe(t),t.style.strokeDasharray=`${w[s]}`;}),me();},150);}return window.addEventListener("resize",q),window.addEventListener("orientationchange",q),le>0?setTimeout(()=>ee.observe(e),le):ee.observe(e),{destroy(){cancelAnimationFrame(A),clearTimeout(U),ee.disconnect(),window.removeEventListener("resize",q),window.removeEventListener("orientationchange",q),clearTimeout(te),Y?.remove();},replay(){C=-1,z=-1,G=-1,W=false,R=false,Q=0,S=false,O.clear(),clearTimeout(U),de();},pause(){S=true,cancelAnimationFrame(A);},resume(){S&&(S=false,V&&(A=requestAnimationFrame(j)));},seek(t){let s=Math.min(1,Math.max(0,t));K=s,C=s,S=true,cancelAnimationFrame(A),Ie(s,k);},getProgress(){return K}}}function He({children:e,className:r,style:n,...o}){let i=useRef(null);return useEffect(()=>{if(!i.current)return;let l=xe(i.current,o);return ()=>l.destroy()},[]),jsx("div",{ref:i,className:r,style:n,children:e})}export{He as ScrollDraw};
|
package/dist/solid/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var solidJs=require('solid-js');var
|
|
2
|
-
<div style="position:absolute;${
|
|
3
|
-
<div style="position:absolute;${
|
|
1
|
+
'use strict';var solidJs=require('solid-js');var re={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 ne(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 ye(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 he(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 oe(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 Ne(e,r,n){return Math.min(n,Math.max(r,e))}function B(e,r,n,o){return n===r?0:Ne((e-r)/(n-r)*o,0,1)}function we(e,r,n,o,a){let c=ye(e.top,e.height,r,o.element)-he(o.viewport,n),u=ye(e.top,e.height,r,a.element)-he(a.viewport,n);return {tStart:c,tEnd:u}}function be(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 se(e,r,n){let o=be(e),a=be(r);return !o||!a?e:`rgb(${Math.round(o[0]+(a[0]-o[0])*n)},${Math.round(o[1]+(a[1]-o[1])*n)},${Math.round(o[2]+(a[2]-o[2])*n)})`}function ve(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}function Oe(e){let r=e.getAttribute("stroke"),n=e.getAttribute("fill");!r||r==="none"?ve("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&ve("Element has a fill \u2014 it may obscure the stroke animation.",e);}function Pe(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 a(){let c=n==="x"?window.scrollX:window.scrollY,u=e-c,E=r-c,P=n==="x";o.innerHTML=`
|
|
2
|
+
<div style="position:absolute;${P?`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;${P?`left:${E}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${E}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 xe(e,r,n){let o=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),a=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,c=>{let u=parseFloat(c),E=o[a++]??u;return String(+(u+(E-u)*n).toFixed(4))})}function ie(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:a=1,fade:c=false,easing:u="linear",trigger:E={},stagger:P=0,direction:k="forward",once:ae=false,debug:$e=false,axis:b="y",scrollContainer:X,autoReverse:le=false,delay:ce=0,strokeColor:D,strokeWidth:M,waypoints:_,velocityScale:j=false,threshold:Ae=0,rootMargin:Se="0px",repeat:ue=0,repeatDelay:Te=0,morphTo:$,onProgress:De,onStart:Me,onComplete:fe}=r,pe=typeof u=="function"?u:re[u]??re.linear,Ie=ne(E.start??"top bottom"),Le=ne(E.end??"bottom top"),p=typeof X=="string"?document.querySelector(X):X??null,v=Array.isArray(D)?D[0]:null,g=Array.isArray(D)?D[1]:typeof D=="string"?D:null,y=Array.isArray(M)?M[0]:null,h=Array.isArray(M)?M[1]:typeof M=="number"?M:null,N=Array.from(e.querySelectorAll(o)),w=[],x=[],I=0,L=0,O=false,W=false,A=0,R=false,C=-1,V=-1,S=false,J=0,K=0,Q,U=null,z=new Set,G=-1,me=performance.now();function Y(){return p?b==="x"?p.scrollLeft:p.scrollTop:b==="x"?window.scrollX:window.scrollY}function Ce(){return p?b==="x"?p.clientWidth:p.clientHeight:b==="x"?window.innerWidth:window.innerHeight}function de(){let t=e.getBoundingClientRect(),s,i,m;if(p){let F=p.getBoundingClientRect();s=b==="x"?t.left-F.left+p.scrollLeft:t.top-F.top+p.scrollTop,i=b==="x"?t.width:t.height,m=Y();}else s=b==="x"?t.left:t.top,i=b==="x"?t.width:t.height,m=Y();let H=we({top:s,height:i},m,Ce(),Ie,Le);I=H.tStart,L=H.tEnd,$e&&process.env.NODE_ENV!=="production"&&(U?.remove(),U=Pe(I,L,b));}function Fe(t,s){N.forEach((i,m)=>{i.style.strokeDashoffset=s==="reverse"?`${w[m]*t}`:`${w[m]*(1-t)}`,c&&(i.style.opacity=s==="reverse"?`${1-t}`:`${t}`),v&&g?i.style.stroke=se(v,g,t):g&&(i.style.stroke=g),y!==null&&h!==null?i.style.strokeWidth=`${y+(h-y)*t}`:h!==null&&(i.style.strokeWidth=`${h}`),$&&i.tagName.toLowerCase()==="path"&&x[m]&&i.setAttribute("d",xe(x[m],$,t));});}function ge(){N.forEach((t,s)=>{t.style.strokeDasharray=`${w[s]}`,t.style.strokeDashoffset=k==="reverse"?"0":`${w[s]}`,c?t.style.opacity=k==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`),$&&t.tagName.toLowerCase()==="path"&&x[s]&&t.setAttribute("d",x[s]);});}if(N.forEach(t=>{Oe(t);let s=oe(t);w.push(s),t.tagName.toLowerCase()==="path"?x.push(t.getAttribute("d")??""):x.push(""),n?(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=k==="reverse"?`${s}`:"0",c&&(t.style.opacity="1"),g&&(t.style.stroke=g),h!==null&&(t.style.strokeWidth=`${h}`),$&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",$)):(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=k==="reverse"?"0":`${s}`,c?t.style.opacity=k==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`));}),n)return fe?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};de();function Z(){if(!R||S)return;let t=performance.now(),s=Y(),i=a;if(j!==false){let l=t-me,d=l>0?Math.abs(s-(G<0?s:G))/l:0;i=a*Math.max(.2,1+d*(typeof j=="number"?j:1)*.04);}G=s,me=t;let m=le?V===-1||s>=V?"forward":"reverse":k;V=s;let H=L-I,F=true;if(N.forEach((l,d)=>{let T=d*P*H,f=pe(B(s,I+T,L+T,i));ae&&!le&&(C=Math.max(C,f),f=C),J=f,l.style.strokeDashoffset=m==="reverse"?`${w[d]*f}`:`${w[d]*(1-f)}`,c&&(l.style.opacity=m==="reverse"?`${1-f}`:`${f}`),v&&g?l.style.stroke=se(v,g,f):g&&(l.style.stroke=g),y!==null&&h!==null?l.style.strokeWidth=`${y+(h-y)*f}`:h!==null&&(l.style.strokeWidth=`${h}`),$&&l.tagName.toLowerCase()==="path"&&x[d]&&l.setAttribute("d",xe(x[d],$,f)),d===0&&De?.(f),f<1&&(F=false);}),_){let l=pe(B(s,I,L,i));for(let d in _){let T=parseFloat(d);l>=T&&!z.has(T)&&(z.add(T),_[d]?.());}}!W&&B(s,I,L,i)>0&&(W=true,Me?.()),F&&!O?(O=true,fe?.(),K<(ue==="infinite"?1/0:ue??0)&&(K++,Q=setTimeout(()=>{C=-1,W=false,O=false,z.clear(),ge();},Te))):!F&&!ae&&(O=false),A=requestAnimationFrame(Z);}let ee=new IntersectionObserver(t=>{t.forEach(s=>{R=s.isIntersecting,R&&!S?A=requestAnimationFrame(Z):cancelAnimationFrame(A);});},{root:p??null,threshold:Ae,rootMargin:Se}),te;function q(){clearTimeout(te),te=setTimeout(()=>{N.forEach((t,s)=>{w[s]=oe(t),t.style.strokeDasharray=`${w[s]}`;}),de();},150);}return window.addEventListener("resize",q),window.addEventListener("orientationchange",q),ce>0?setTimeout(()=>ee.observe(e),ce):ee.observe(e),{destroy(){cancelAnimationFrame(A),clearTimeout(Q),ee.disconnect(),window.removeEventListener("resize",q),window.removeEventListener("orientationchange",q),clearTimeout(te),U?.remove();},replay(){C=-1,V=-1,G=-1,W=false,O=false,K=0,S=false,z.clear(),clearTimeout(Q),ge();},pause(){S=true,cancelAnimationFrame(A);},resume(){S&&(S=false,R&&(A=requestAnimationFrame(Z)));},seek(t){let s=Math.min(1,Math.max(0,t));J=s,C=s,S=true,cancelAnimationFrame(A),Fe(s,k);},getProgress(){return J}}}function qe(e={}){let r,n;return solidJs.onMount(()=>{r&&(n=ie(r,e));}),solidJs.onCleanup(()=>{n?.destroy();}),o=>{r=o;}}function He(e={}){let r,n;return solidJs.onMount(()=>{r&&(n=ie(r,e));}),solidJs.onCleanup(()=>{n?.destroy(),n=void 0;}),{ref:o=>{r=o;},getInstance:()=>n}}exports.createScrollDraw=He;exports.useScrollDraw=qe;
|
package/dist/solid/index.d.mts
CHANGED
|
@@ -19,7 +19,7 @@ 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
|
|
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];
|
|
@@ -27,6 +27,18 @@ interface ScrollDrawOptions {
|
|
|
27
27
|
strokeWidth?: number | [number, number];
|
|
28
28
|
/** Fire callbacks at specific progress thresholds (0–1). Resets on replay(). */
|
|
29
29
|
waypoints?: Record<number, () => void>;
|
|
30
|
+
/** Scale animation speed by scroll velocity — faster scrolling = faster draw. Pass a number to control sensitivity (default 1). */
|
|
31
|
+
velocityScale?: boolean | number;
|
|
32
|
+
/** IntersectionObserver threshold (0–1). Default 0. */
|
|
33
|
+
threshold?: number;
|
|
34
|
+
/** IntersectionObserver rootMargin. Default "0px". */
|
|
35
|
+
rootMargin?: string;
|
|
36
|
+
/** Repeat the animation N times after completion. Use 'infinite' to loop forever. */
|
|
37
|
+
repeat?: number | 'infinite';
|
|
38
|
+
/** Milliseconds to wait between repeats. Default 0. */
|
|
39
|
+
repeatDelay?: number;
|
|
40
|
+
/** Target path `d` attribute to morph toward as the animation progresses. Paths must have compatible structures. */
|
|
41
|
+
morphTo?: string;
|
|
30
42
|
onProgress?: (alpha: number) => void;
|
|
31
43
|
onStart?: () => void;
|
|
32
44
|
onComplete?: () => void;
|
|
@@ -35,6 +47,14 @@ interface ScrollDrawInstance {
|
|
|
35
47
|
destroy: () => void;
|
|
36
48
|
/** Reset and replay the animation from the beginning. */
|
|
37
49
|
replay: () => void;
|
|
50
|
+
/** Pause the animation at the current progress. */
|
|
51
|
+
pause: () => void;
|
|
52
|
+
/** Resume a paused animation. */
|
|
53
|
+
resume: () => void;
|
|
54
|
+
/** Jump to a specific progress value (0–1) and pause. */
|
|
55
|
+
seek: (progress: number) => void;
|
|
56
|
+
/** Returns current draw progress (0–1). */
|
|
57
|
+
getProgress: () => number;
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
/**
|
package/dist/solid/index.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ 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
|
|
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];
|
|
@@ -27,6 +27,18 @@ interface ScrollDrawOptions {
|
|
|
27
27
|
strokeWidth?: number | [number, number];
|
|
28
28
|
/** Fire callbacks at specific progress thresholds (0–1). Resets on replay(). */
|
|
29
29
|
waypoints?: Record<number, () => void>;
|
|
30
|
+
/** Scale animation speed by scroll velocity — faster scrolling = faster draw. Pass a number to control sensitivity (default 1). */
|
|
31
|
+
velocityScale?: boolean | number;
|
|
32
|
+
/** IntersectionObserver threshold (0–1). Default 0. */
|
|
33
|
+
threshold?: number;
|
|
34
|
+
/** IntersectionObserver rootMargin. Default "0px". */
|
|
35
|
+
rootMargin?: string;
|
|
36
|
+
/** Repeat the animation N times after completion. Use 'infinite' to loop forever. */
|
|
37
|
+
repeat?: number | 'infinite';
|
|
38
|
+
/** Milliseconds to wait between repeats. Default 0. */
|
|
39
|
+
repeatDelay?: number;
|
|
40
|
+
/** Target path `d` attribute to morph toward as the animation progresses. Paths must have compatible structures. */
|
|
41
|
+
morphTo?: string;
|
|
30
42
|
onProgress?: (alpha: number) => void;
|
|
31
43
|
onStart?: () => void;
|
|
32
44
|
onComplete?: () => void;
|
|
@@ -35,6 +47,14 @@ interface ScrollDrawInstance {
|
|
|
35
47
|
destroy: () => void;
|
|
36
48
|
/** Reset and replay the animation from the beginning. */
|
|
37
49
|
replay: () => void;
|
|
50
|
+
/** Pause the animation at the current progress. */
|
|
51
|
+
pause: () => void;
|
|
52
|
+
/** Resume a paused animation. */
|
|
53
|
+
resume: () => void;
|
|
54
|
+
/** Jump to a specific progress value (0–1) and pause. */
|
|
55
|
+
seek: (progress: number) => void;
|
|
56
|
+
/** Returns current draw progress (0–1). */
|
|
57
|
+
getProgress: () => number;
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
/**
|
package/dist/solid/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {onMount,onCleanup}from'solid-js';var
|
|
2
|
-
<div style="position:absolute;${
|
|
3
|
-
<div style="position:absolute;${
|
|
1
|
+
import {onMount,onCleanup}from'solid-js';var re={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 ne(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 ye(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 he(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 oe(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 Ne(e,r,n){return Math.min(n,Math.max(r,e))}function B(e,r,n,o){return n===r?0:Ne((e-r)/(n-r)*o,0,1)}function we(e,r,n,o,a){let c=ye(e.top,e.height,r,o.element)-he(o.viewport,n),u=ye(e.top,e.height,r,a.element)-he(a.viewport,n);return {tStart:c,tEnd:u}}function be(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 se(e,r,n){let o=be(e),a=be(r);return !o||!a?e:`rgb(${Math.round(o[0]+(a[0]-o[0])*n)},${Math.round(o[1]+(a[1]-o[1])*n)},${Math.round(o[2]+(a[2]-o[2])*n)})`}function ve(e,r){process.env.NODE_ENV!=="production"&&console.warn(`[svg-scroll-draw] ${e}`,r);}function Oe(e){let r=e.getAttribute("stroke"),n=e.getAttribute("fill");!r||r==="none"?ve("Element has no stroke \u2014 path will not be visible.",e):n&&n!=="none"&&n!=="transparent"&&ve("Element has a fill \u2014 it may obscure the stroke animation.",e);}function Pe(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 a(){let c=n==="x"?window.scrollX:window.scrollY,u=e-c,E=r-c,P=n==="x";o.innerHTML=`
|
|
2
|
+
<div style="position:absolute;${P?`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;${P?`left:${E}px;top:0;bottom:0;border-left:2px dashed #ef4444;`:`top:${E}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 xe(e,r,n){let o=(r.match(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g)??[]).map(Number),a=0;return e.replace(/[-+]?(?:\d*\.)?\d+(?:[eE][-+]?\d+)?/g,c=>{let u=parseFloat(c),E=o[a++]??u;return String(+(u+(E-u)*n).toFixed(4))})}function ie(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:a=1,fade:c=false,easing:u="linear",trigger:E={},stagger:P=0,direction:k="forward",once:ae=false,debug:$e=false,axis:b="y",scrollContainer:X,autoReverse:le=false,delay:ce=0,strokeColor:D,strokeWidth:M,waypoints:_,velocityScale:j=false,threshold:Ae=0,rootMargin:Se="0px",repeat:ue=0,repeatDelay:Te=0,morphTo:$,onProgress:De,onStart:Me,onComplete:fe}=r,pe=typeof u=="function"?u:re[u]??re.linear,Ie=ne(E.start??"top bottom"),Le=ne(E.end??"bottom top"),p=typeof X=="string"?document.querySelector(X):X??null,v=Array.isArray(D)?D[0]:null,g=Array.isArray(D)?D[1]:typeof D=="string"?D:null,y=Array.isArray(M)?M[0]:null,h=Array.isArray(M)?M[1]:typeof M=="number"?M:null,N=Array.from(e.querySelectorAll(o)),w=[],x=[],I=0,L=0,O=false,W=false,A=0,R=false,C=-1,V=-1,S=false,J=0,K=0,Q,U=null,z=new Set,G=-1,me=performance.now();function Y(){return p?b==="x"?p.scrollLeft:p.scrollTop:b==="x"?window.scrollX:window.scrollY}function Ce(){return p?b==="x"?p.clientWidth:p.clientHeight:b==="x"?window.innerWidth:window.innerHeight}function de(){let t=e.getBoundingClientRect(),s,i,m;if(p){let F=p.getBoundingClientRect();s=b==="x"?t.left-F.left+p.scrollLeft:t.top-F.top+p.scrollTop,i=b==="x"?t.width:t.height,m=Y();}else s=b==="x"?t.left:t.top,i=b==="x"?t.width:t.height,m=Y();let H=we({top:s,height:i},m,Ce(),Ie,Le);I=H.tStart,L=H.tEnd,$e&&process.env.NODE_ENV!=="production"&&(U?.remove(),U=Pe(I,L,b));}function Fe(t,s){N.forEach((i,m)=>{i.style.strokeDashoffset=s==="reverse"?`${w[m]*t}`:`${w[m]*(1-t)}`,c&&(i.style.opacity=s==="reverse"?`${1-t}`:`${t}`),v&&g?i.style.stroke=se(v,g,t):g&&(i.style.stroke=g),y!==null&&h!==null?i.style.strokeWidth=`${y+(h-y)*t}`:h!==null&&(i.style.strokeWidth=`${h}`),$&&i.tagName.toLowerCase()==="path"&&x[m]&&i.setAttribute("d",xe(x[m],$,t));});}function ge(){N.forEach((t,s)=>{t.style.strokeDasharray=`${w[s]}`,t.style.strokeDashoffset=k==="reverse"?"0":`${w[s]}`,c?t.style.opacity=k==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`),$&&t.tagName.toLowerCase()==="path"&&x[s]&&t.setAttribute("d",x[s]);});}if(N.forEach(t=>{Oe(t);let s=oe(t);w.push(s),t.tagName.toLowerCase()==="path"?x.push(t.getAttribute("d")??""):x.push(""),n?(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=k==="reverse"?`${s}`:"0",c&&(t.style.opacity="1"),g&&(t.style.stroke=g),h!==null&&(t.style.strokeWidth=`${h}`),$&&t.tagName.toLowerCase()==="path"&&t.setAttribute("d",$)):(t.style.strokeDasharray=`${s}`,t.style.strokeDashoffset=k==="reverse"?"0":`${s}`,c?t.style.opacity=k==="reverse"?"1":"0":t.style.opacity="",v&&(t.style.stroke=v),y!==null&&(t.style.strokeWidth=`${y}`));}),n)return fe?.(),{destroy:()=>{},replay:()=>{},pause:()=>{},resume:()=>{},seek:()=>{},getProgress:()=>1};de();function Z(){if(!R||S)return;let t=performance.now(),s=Y(),i=a;if(j!==false){let l=t-me,d=l>0?Math.abs(s-(G<0?s:G))/l:0;i=a*Math.max(.2,1+d*(typeof j=="number"?j:1)*.04);}G=s,me=t;let m=le?V===-1||s>=V?"forward":"reverse":k;V=s;let H=L-I,F=true;if(N.forEach((l,d)=>{let T=d*P*H,f=pe(B(s,I+T,L+T,i));ae&&!le&&(C=Math.max(C,f),f=C),J=f,l.style.strokeDashoffset=m==="reverse"?`${w[d]*f}`:`${w[d]*(1-f)}`,c&&(l.style.opacity=m==="reverse"?`${1-f}`:`${f}`),v&&g?l.style.stroke=se(v,g,f):g&&(l.style.stroke=g),y!==null&&h!==null?l.style.strokeWidth=`${y+(h-y)*f}`:h!==null&&(l.style.strokeWidth=`${h}`),$&&l.tagName.toLowerCase()==="path"&&x[d]&&l.setAttribute("d",xe(x[d],$,f)),d===0&&De?.(f),f<1&&(F=false);}),_){let l=pe(B(s,I,L,i));for(let d in _){let T=parseFloat(d);l>=T&&!z.has(T)&&(z.add(T),_[d]?.());}}!W&&B(s,I,L,i)>0&&(W=true,Me?.()),F&&!O?(O=true,fe?.(),K<(ue==="infinite"?1/0:ue??0)&&(K++,Q=setTimeout(()=>{C=-1,W=false,O=false,z.clear(),ge();},Te))):!F&&!ae&&(O=false),A=requestAnimationFrame(Z);}let ee=new IntersectionObserver(t=>{t.forEach(s=>{R=s.isIntersecting,R&&!S?A=requestAnimationFrame(Z):cancelAnimationFrame(A);});},{root:p??null,threshold:Ae,rootMargin:Se}),te;function q(){clearTimeout(te),te=setTimeout(()=>{N.forEach((t,s)=>{w[s]=oe(t),t.style.strokeDasharray=`${w[s]}`;}),de();},150);}return window.addEventListener("resize",q),window.addEventListener("orientationchange",q),ce>0?setTimeout(()=>ee.observe(e),ce):ee.observe(e),{destroy(){cancelAnimationFrame(A),clearTimeout(Q),ee.disconnect(),window.removeEventListener("resize",q),window.removeEventListener("orientationchange",q),clearTimeout(te),U?.remove();},replay(){C=-1,V=-1,G=-1,W=false,O=false,K=0,S=false,z.clear(),clearTimeout(Q),ge();},pause(){S=true,cancelAnimationFrame(A);},resume(){S&&(S=false,R&&(A=requestAnimationFrame(Z)));},seek(t){let s=Math.min(1,Math.max(0,t));J=s,C=s,S=true,cancelAnimationFrame(A),Fe(s,k);},getProgress(){return J}}}function qe(e={}){let r,n;return onMount(()=>{r&&(n=ie(r,e));}),onCleanup(()=>{n?.destroy();}),o=>{r=o;}}function He(e={}){let r,n;return onMount(()=>{r&&(n=ie(r,e));}),onCleanup(()=>{n?.destroy(),n=void 0;}),{ref:o=>{r=o;},getInstance:()=>n}}export{He as createScrollDraw,qe as useScrollDraw};
|