svg-scroll-draw 2.12.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -2
- package/dist/cdn/vivus.global.js +1 -0
- package/dist/cli/init.js +284 -13
- package/dist/vivus/index.cjs +2 -0
- package/dist/vivus/index.d.mts +100 -0
- package/dist/vivus/index.d.ts +100 -0
- package/dist/vivus/index.mjs +2 -0
- package/package.json +22 -3
package/README.md
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
| `devtools` | `svg-scroll-draw/devtools` | Visual overlay showing every active animation's triggers and progress. Dev-only. |
|
|
33
33
|
| `AOS` | `svg-scroll-draw/aos` | Drop-in replacement for AOS: same `AOS.init()`, same `data-aos` markup, no `aos.css`. |
|
|
34
34
|
| `ScrollReveal` | `svg-scroll-draw/scrollreveal` | Drop-in replacement for ScrollReveal.js 4, MIT instead of GPL-3.0. |
|
|
35
|
+
| `Vivus` | `svg-scroll-draw/vivus` | Drop-in replacement for vivus 0.4: same `new Vivus()` API and output. |
|
|
35
36
|
|
|
36
37
|
All APIs return the same instance object: `{ destroy, replay, pause, resume, seek, getProgress }`.
|
|
37
38
|
|
|
@@ -362,7 +363,7 @@ import { ScrollDraw } from 'svg-scroll-draw/vue';
|
|
|
362
363
|
## AOS drop-in — switch from AOS in one line
|
|
363
364
|
|
|
364
365
|
Already using [AOS](https://github.com/michalsnik/aos)? `svg-scroll-draw/aos` speaks its API and
|
|
365
|
-
reads its markup, so the move is an import change
|
|
366
|
+
reads its markup, so the move is an import change — or one command: `npx svg-scroll-draw migrate`. Keep every `data-aos`, `data-aos-offset`,
|
|
366
367
|
`data-aos-delay`, `data-aos-anchor-placement` and custom animation; delete `aos.css` — the styles ship
|
|
367
368
|
inside the module. 3.0 KB gzipped with the styles, against 6.7 KB for AOS 2.3.4 with its stylesheet.
|
|
368
369
|
|
|
@@ -402,7 +403,8 @@ Differences, on purpose:
|
|
|
402
403
|
|
|
403
404
|
On [ScrollReveal](https://scrollrevealjs.org)? It is GPL-3.0 (with a paid licence for commercial work)
|
|
404
405
|
and has not shipped since 4.0.9. `svg-scroll-draw/scrollreveal` is an independent, MIT-licensed
|
|
405
|
-
implementation of the same API, so the move is an import change
|
|
406
|
+
implementation of the same API, so the move is an import change — or one command: `npx svg-scroll-draw migrate`.
|
|
407
|
+
4.5 KB gzipped, against 5.6 KB.
|
|
406
408
|
|
|
407
409
|
```diff
|
|
408
410
|
- import ScrollReveal from 'scrollreveal';
|
|
@@ -430,6 +432,36 @@ Differences, on purpose:
|
|
|
430
432
|
|
|
431
433
|
---
|
|
432
434
|
|
|
435
|
+
## vivus drop-in — keep your `new Vivus()` code
|
|
436
|
+
|
|
437
|
+
On [vivus](https://github.com/maxwellito/vivus)? It has not shipped since 0.4.6 (April 2021).
|
|
438
|
+
`svg-scroll-draw/vivus` runs the same API, so the move is an import change — or one command:
|
|
439
|
+
`npx svg-scroll-draw migrate`. 3.9 KB gzipped, against 4.1 KB.
|
|
440
|
+
|
|
441
|
+
```diff
|
|
442
|
+
- import Vivus from 'vivus';
|
|
443
|
+
+ import Vivus from 'svg-scroll-draw/vivus';
|
|
444
|
+
|
|
445
|
+
new Vivus('my-svg', { type: 'oneByOne', duration: 200 }, () => console.log('drawn'));
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
No bundler? `<script src="https://unpkg.com/svg-scroll-draw/dist/cdn/vivus.global.js"></script>`
|
|
449
|
+
defines `window.Vivus`. With CommonJS, `require('svg-scroll-draw/vivus').default` is the class.
|
|
450
|
+
|
|
451
|
+
Every option, every animation type (`delayed`, `sync`, `async`, `nsync`, `oneByOne`, `scenario`,
|
|
452
|
+
`scenario-sync`), the `start` modes, `file` and `<object>` loading, the `data-start` / `data-duration` /
|
|
453
|
+
`data-delay` / `data-async` / `data-ignore` attributes, `Vivus.EASE` and the other timing functions, and
|
|
454
|
+
`play` / `stop` / `reset` / `finish` / `setFrameProgress` / `getStatus` / `destroy` / `recalc` behave as
|
|
455
|
+
in 0.4.6. Shapes become `<path>`s with the same `d` strings, and dashes get the same values: the browser
|
|
456
|
+
suite runs vivus 0.4.6 beside it across nine configurations and requires the SVG markup to match exactly
|
|
457
|
+
at every point of the animation. Like vivus, the clock is the animation frame.
|
|
458
|
+
|
|
459
|
+
One difference, on purpose: under `prefers-reduced-motion: reduce`, `play()` jumps to the end and still
|
|
460
|
+
fires its callbacks. When you want the stroke to follow the scroll instead of a clock, use
|
|
461
|
+
[`scrollDraw`](#scrolldraw--svg-path-drawing-v1-api-unchanged) from the same package.
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
433
465
|
## Instance API
|
|
434
466
|
|
|
435
467
|
Every function returns the same instance object:
|
|
@@ -522,6 +554,7 @@ devtools.highlight('#my-element'); // outline for 2 seconds
|
|
|
522
554
|
| `svg-scroll-draw/devtools` | `devtools` (dev-only) |
|
|
523
555
|
| `svg-scroll-draw/aos` | `AOS` (default), `init`, `refresh`, `refreshHard`, `destroy` |
|
|
524
556
|
| `svg-scroll-draw/scrollreveal` | `ScrollReveal` (default and named) |
|
|
557
|
+
| `svg-scroll-draw/vivus` | `Vivus` (default and named) |
|
|
525
558
|
|
|
526
559
|
---
|
|
527
560
|
|
|
@@ -535,6 +568,7 @@ devtools.highlight('#my-element'); // outline for 2 seconds
|
|
|
535
568
|
| `svg-scroll-draw/text` | 2.5 KB |
|
|
536
569
|
| `svg-scroll-draw/video` | 2.0 KB |
|
|
537
570
|
| `svg-scroll-draw/scrollreveal` | 4.5 KB |
|
|
571
|
+
| `svg-scroll-draw/vivus` | 3.9 KB |
|
|
538
572
|
| `svg-scroll-draw/aos` (styles included) | 3.0 KB |
|
|
539
573
|
| `svg-scroll-draw/snap` | 1.7 KB |
|
|
540
574
|
| `svg-scroll-draw/devtools` | 1.7 KB (dev only) |
|
|
@@ -571,6 +605,19 @@ npx svg-scroll-draw init
|
|
|
571
605
|
|
|
572
606
|
Scaffolds a ready-to-use starter file for React, Vue, Svelte, Solid, or Vanilla JS.
|
|
573
607
|
|
|
608
|
+
### Switching from AOS, ScrollReveal or vivus
|
|
609
|
+
|
|
610
|
+
```bash
|
|
611
|
+
npx svg-scroll-draw migrate --dry-run # see what would change
|
|
612
|
+
npx svg-scroll-draw migrate # apply it
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
Points every `import` / `require` of `aos`, `scrollreveal` and `vivus` at the matching drop-in, swaps CDN
|
|
616
|
+
`<script>` tags for the script-tag builds (dropping any stale `integrity` hash), removes AOS's `aos.css`
|
|
617
|
+
imports, `<link>`s and `@import`s, and swaps the dependency in `package.json`. It rewrites module names,
|
|
618
|
+
URLs and dependency entries only — never the code that uses them — skips `node_modules` and build output,
|
|
619
|
+
and will not write over uncommitted git changes unless you pass `--force`.
|
|
620
|
+
|
|
574
621
|
---
|
|
575
622
|
|
|
576
623
|
## Browser support
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(()=>{function g(){return typeof window>"u"||typeof window.matchMedia!="function"?!1:window.matchMedia("(prefers-reduced-motion: reduce)").matches}function m(r,...t){}var E=["delayed","sync","async","nsync","oneByOne","scenario","scenario-sync"],L=["inViewport","manual","autostart"];function u(r,t){let e=parseInt(r,10);return e>=0?e:t}function V(r){if(typeof window>"u")return!1;let t=window,e=i=>typeof t[i]=="function"&&r instanceof t[i];return e("SVGSVGElement")||e("SVGGElement")||r?.constructor===t.SVGElement}var y=["cx","cy","points","r","rx","ry","x","x1","x2","y","y1","y2"],$=["line","ellipse","circle","polygon","polyline","rect"],S="http://www.w3.org/2000/svg";function v(r){let t=r.points.trim().split(" ");if(r.points.indexOf(",")===-1){let i=[];for(let s=0;s<t.length;s+=2)i.push(`${t[s]},${t[s+1]}`);t=i}let e=`M${t[0]}`;for(let i=1;i<t.length;i++)t[i].indexOf(",")!==-1&&(e+=`L${t[i]}`);return e}function b(r,t,e,i){let s=parseFloat(e)||0,a=parseFloat(i)||0,n=parseFloat(r)||0,o=parseFloat(t)||0,l=n-s,h=n+s;return`M${l},${o}A${s},${a} 0,1,1 ${h},${o}A${s},${a} 0,1,1 ${l},${o}`}var x={line:r=>`M${r.x1||0},${r.y1||0}L${r.x2||0},${r.y2||0}`,rect(r){let t=parseFloat(r.x)||0,e=parseFloat(r.y)||0,i=parseFloat(r.width)||0,s=parseFloat(r.height)||0;if(r.rx||r.ry){let a=parseInt(r.rx,10)||-1,n=parseInt(r.ry,10)||-1;a=Math.min(Math.max(a<0?n:a,0),i/2),n=Math.min(Math.max(n<0?a:n,0),s/2);let o=`A ${a},${n},0,0,1,`;return`M ${t+a},${e} L ${t+i-a},${e} ${o}${t+i},${e+n} L ${t+i},${e+s-n} ${o}${t+i-a},${e+s} L ${t+a},${e+s} ${o}${t},${e+s-n} L ${t},${e+n} ${o}${t+a},${e}`}return`M${t} ${e} L${t+i} ${e} L${t+i} ${e+s} L${t} ${e+s} Z`},polyline:v,polygon:r=>`${v(r)}Z`,ellipse:r=>b(r.cx,r.cy,r.rx,r.ry),circle:r=>b(r.cx,r.cy,r.r,r.r)};function A(r){for(let t of Array.from(r.querySelectorAll($.join(",")))){let e={};for(let{name:a,value:n}of Array.from(t.attributes)){if(y.indexOf(a)!==-1&&n.indexOf("%")!==-1)throw new Error("Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into 'path' tags. Please use 'viewBox'.");e[a]=n}let i=x[t.tagName.toLowerCase()](e),s=document.createElementNS(S,"path");for(let{name:a,value:n}of Array.from(t.attributes))y.indexOf(a)===-1&&s.setAttribute(a,n);s.setAttribute("d",i),t.parentNode?.replaceChild(s,t)}}var c=class c{constructor(t,e,i){this.isReady=!1;this.type="delayed";this.start="inViewport";this.duration=120;this.delay=null;this.dashGap=1;this.forceRender=!1;this.reverseStack=!1;this.selfDestroy=!1;this.ignoreInvisible=!1;this.animTimingFunction=c.LINEAR;this.pathTimingFunction=c.LINEAR;this.callback=()=>{};this.map=[];this.frameLength=0;this.currentFrame=0;this.delayUnit=0;this.speed=1;this.handle=null;this.instanceCallback=null;this.mustRecalcScale=null;this.viewportListener=null;this.setElement(t,e),this.setOptions(e),this.setCallback(i),this.isReady&&this.init()}setElement(t,e){if(t===void 0)throw new Error('Vivus [constructor]: "element" parameter is required');let i=t;if(typeof i=="string"){let s=document.getElementById(i);if(!s)throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');i=s}if(this.parentEl=i,e&&e.file){let s=new XMLHttpRequest;s.addEventListener("load",()=>{let a=document.createElement("div");a.innerHTML=s.responseText;let n=a.querySelector("svg");if(!n)throw new Error(`Vivus [load]: Cannot find the SVG in the loaded file : ${e.file}`);this.el=n,n.setAttribute("width","100%"),n.setAttribute("height","100%"),this.parentEl.appendChild(n),this.isReady=!0,this.init()}),s.open("GET",e.file),s.send();return}if(V(i)){this.el=i,this.isReady=!0;return}if(i instanceof HTMLObjectElement){let s=i,a=n=>{if(this.isReady)return;let o=s.contentDocument&&s.contentDocument.querySelector("svg");if(!o&&n)throw new Error("Vivus [constructor]: object loaded does not contain any SVG");o&&(s.getAttribute("built-by-vivus")&&(this.parentEl.insertBefore(o,s),this.parentEl.removeChild(s),o.setAttribute("width","100%"),o.setAttribute("height","100%")),this.el=o,this.isReady=!0,this.init())};a(),this.isReady||s.addEventListener("load",a);return}throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)')}setOptions(t){if(t!==void 0&&(t===null||t.constructor!==Object))throw new Error('Vivus [constructor]: "options" parameter must be an object');let e=t||{};if(e.type&&E.indexOf(e.type)===-1)throw new Error(`Vivus [constructor]: ${e.type} is not an existing animation \`type\``);if(e.start&&L.indexOf(e.start)===-1)throw new Error(`Vivus [constructor]: ${e.start} is not an existing \`start\` option`);this.type=e.type||"delayed",this.start=e.start||"inViewport";let i=navigator.userAgent,s=i.indexOf("MSIE")!==-1||i.indexOf("Trident/")!==-1||i.indexOf("Edge/")!==-1;if(this.duration=u(e.duration,120),this.delay=u(e.delay,null),this.dashGap=u(e.dashGap,1),this.forceRender=Object.prototype.hasOwnProperty.call(e,"forceRender")?!!e.forceRender:s,this.reverseStack=!!e.reverseStack,this.selfDestroy=!!e.selfDestroy,this.onReady=e.onReady,this.map=[],this.ignoreInvisible=Object.prototype.hasOwnProperty.call(e,"ignoreInvisible")?!!e.ignoreInvisible:!1,this.animTimingFunction=e.animTimingFunction||c.LINEAR,this.pathTimingFunction=e.pathTimingFunction||c.LINEAR,this.delay!==null&&this.delay>=this.duration)throw new Error("Vivus [constructor]: delay must be shorter than duration")}setCallback(t){if(t&&typeof t!="function")throw new Error('Vivus [constructor]: "callback" parameter must be a function');this.callback=t||(()=>{})}mapping(){let t=0,e=0,i=0,s=!1,a=Array.from(this.el.querySelectorAll("path"));a.forEach((n,o)=>{if(this.isInvisible(n))return;let l={el:n,length:0,startAt:0,duration:0,isResizeSensitive:!1},h=1;if(n.getAttribute("vector-effect")==="non-scaling-stroke"){let d=n.getBoundingClientRect(),f=n.getBBox();h=Math.max(d.width/f.width,d.height/f.height),l.isResizeSensitive=!0,s=!0}if(l.length=Math.ceil(n.getTotalLength()*h),isNaN(l.length)){m("vivus: cannot retrieve a path element length",n);return}this.map.push(l),n.style.strokeDasharray=`${l.length} ${l.length+this.dashGap*2}`,n.style.strokeDashoffset=String(l.length+this.dashGap),l.length+=this.dashGap,e+=l.length,this.renderPath(o)}),s&&m("vivus: this SVG contains non-scaling-strokes. Call instance.recalc() when the SVG is resized."),e=e===0?1:e,this.delay=this.delay===null?this.duration/3:this.delay,this.delayUnit=this.delay/(a.length>1?a.length-1:1),this.reverseStack&&this.map.reverse(),this.map.forEach((n,o)=>{let l=()=>{let h={};for(let{name:d,value:f}of Array.from(n.el.attributes))h[d]=f;return h};switch(this.type){case"delayed":n.startAt=this.delayUnit*o,n.duration=this.duration-this.delay;break;case"oneByOne":n.startAt=i/e*this.duration,n.duration=n.length/e*this.duration;break;case"sync":case"async":case"nsync":n.startAt=0,n.duration=this.duration;break;case"scenario-sync":{let h=l();n.startAt=t+(u(h["data-delay"],this.delayUnit)||0),n.duration=u(h["data-duration"],this.duration),t=h["data-async"]!==void 0?n.startAt:n.startAt+n.duration,this.frameLength=Math.max(this.frameLength,n.startAt+n.duration);break}case"scenario":{let h=l();n.startAt=u(h["data-start"],this.delayUnit)||0,n.duration=u(h["data-duration"],this.duration),this.frameLength=Math.max(this.frameLength,n.startAt+n.duration);break}}i+=n.length,this.frameLength=this.frameLength||this.duration})}recalc(){this.mustRecalcScale||(this.mustRecalcScale=requestAnimationFrame(()=>this.performLineRecalc()))}performLineRecalc(){for(let t of this.map){if(!t.isResizeSensitive)continue;let e=t.el.getBoundingClientRect(),i=t.el.getBBox(),s=Math.max(e.width/i.width,e.height/i.height);t.length=Math.ceil(t.el.getTotalLength()*s),t.el.style.strokeDasharray=`${t.length} ${t.length+this.dashGap*2}`}this.trace(),this.mustRecalcScale=null}draw(){if(this.currentFrame+=this.speed,this.currentFrame<=0)this.stop(),this.reset();else if(this.currentFrame>=this.frameLength)this.stop(),this.currentFrame=this.frameLength,this.trace(),this.selfDestroy&&this.destroy();else{this.trace(),this.handle=requestAnimationFrame(()=>this.draw());return}this.finished()}finished(){if(this.callback(this),this.instanceCallback){let t=this.instanceCallback;this.instanceCallback=null,t(this)}}trace(){let t=this.animTimingFunction(this.currentFrame/this.frameLength)*this.frameLength;this.map.forEach((e,i)=>{let s=this.pathTimingFunction(Math.max(0,Math.min(1,(t-e.startAt)/e.duration)));e.progress!==s&&(e.progress=s,e.el.style.strokeDashoffset=String(Math.floor(e.length*(1-s))),this.renderPath(i))})}renderPath(t){let e=this.forceRender&&this.map&&this.map[t];if(!e)return;let i=e.el.cloneNode(!0);e.el.parentNode?.replaceChild(i,e.el),e.el=i}init(){this.frameLength=0,this.currentFrame=0,this.map=[],A(this.el),this.mapping(),this.starter(),this.onReady&&this.onReady(this)}starter(){if(this.start==="manual")return;if(this.start==="autostart"){this.play();return}let t=()=>{this.isInViewport(this.parentEl,1)&&(this.play(),window.removeEventListener("scroll",t),this.viewportListener=null)};this.viewportListener=t,window.addEventListener("scroll",t),t()}getStatus(){return this.currentFrame===0?"start":this.currentFrame===this.frameLength?"end":"progress"}reset(){return this.setFrameProgress(0)}finish(){return this.setFrameProgress(1)}setFrameProgress(t){let e=Math.min(1,Math.max(0,t));return this.currentFrame=Math.round(this.frameLength*e),this.trace(),this}play(t,e){this.instanceCallback=null;let i=t;if(i&&typeof i=="function")this.instanceCallback=i,i=void 0;else if(i&&typeof i!="number")throw new Error("Vivus [play]: invalid speed");return e&&typeof e=="function"&&!this.instanceCallback&&(this.instanceCallback=e),this.speed=i||1,g()?(this.stop(),this.currentFrame=this.speed<0?0:this.frameLength,this.trace(),this.speed>0&&this.selfDestroy&&this.destroy(),this.finished(),this):(this.handle||this.draw(),this)}stop(){return this.handle&&(cancelAnimationFrame(this.handle),this.handle=null),this}destroy(){this.stop(),this.viewportListener&&(window.removeEventListener("scroll",this.viewportListener),this.viewportListener=null),this.map.forEach((t,e)=>{t.el.style.strokeDashoffset="",t.el.style.strokeDasharray="",this.renderPath(e)})}isInvisible(t){let e=t.getAttribute("data-ignore");if(e!==null)return e!=="false";if(this.ignoreInvisible){let i=t.getBoundingClientRect();return!i.width&&!i.height}return!1}isInViewport(t,e=0){let i=window.pageYOffset||document.documentElement.scrollTop,s=i+Math.max(document.documentElement.clientHeight,window.innerHeight),a=t.getBoundingClientRect(),n=i+a.top;return n+a.height*(e||0)<=s&&n+a.height>=i}};c.LINEAR=t=>t,c.EASE=t=>-Math.cos(t*Math.PI)/2+.5,c.EASE_OUT=t=>1-Math.pow(1-t,3),c.EASE_IN=t=>Math.pow(t,3),c.EASE_OUT_BOUNCE=t=>{let e=-Math.cos(t*(.5*Math.PI))+1,i=Math.pow(e,1.5),s=Math.pow(1-t,2),a=-Math.abs(Math.cos(i*(2.5*Math.PI)))+1;return 1-s+a*s};var p=c,w=p;globalThis.Vivus=w;})();
|
package/dist/cli/init.js
CHANGED
|
@@ -25,8 +25,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
|
|
26
26
|
// src/cli/init.ts
|
|
27
27
|
var readline = __toESM(require("readline"));
|
|
28
|
-
var
|
|
29
|
-
var
|
|
28
|
+
var fs2 = __toESM(require("fs"));
|
|
29
|
+
var path2 = __toESM(require("path"));
|
|
30
30
|
|
|
31
31
|
// src/cli/generators.ts
|
|
32
32
|
var SAMPLE_SVG_JSX = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100">
|
|
@@ -138,6 +138,254 @@ function needsSelector(framework) {
|
|
|
138
138
|
return framework === "vanilla";
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
// src/cli/migrate.ts
|
|
142
|
+
var fs = __toESM(require("fs"));
|
|
143
|
+
var path = __toESM(require("path"));
|
|
144
|
+
var import_node_child_process = require("child_process");
|
|
145
|
+
var LIBS = ["aos", "scrollreveal", "vivus"];
|
|
146
|
+
var LABEL = { aos: "AOS", scrollreveal: "ScrollReveal", vivus: "vivus" };
|
|
147
|
+
var esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
148
|
+
function rewriteSpecifiers(src, changes) {
|
|
149
|
+
let out = src;
|
|
150
|
+
for (const lib of LIBS) {
|
|
151
|
+
const spec = lib === "aos" ? `aos(?:\\/dist\\/aos(?:\\.js)?)?` : esc(lib);
|
|
152
|
+
const target = `svg-scroll-draw/${lib}`;
|
|
153
|
+
const fromRe = new RegExp(`(\\bfrom\\s*)(['"])${spec}\\2`, "g");
|
|
154
|
+
const dynRe = new RegExp(`(\\bimport\\s*\\(\\s*)(['"])${spec}\\2(\\s*\\))`, "g");
|
|
155
|
+
const reqRe = new RegExp(`(\\brequire\\s*\\(\\s*)(['"])${spec}\\2(\\s*\\))`, "g");
|
|
156
|
+
let n = 0;
|
|
157
|
+
out = out.replace(fromRe, (_m, pre, q) => {
|
|
158
|
+
n++;
|
|
159
|
+
return `${pre}${q}${target}${q}`;
|
|
160
|
+
});
|
|
161
|
+
out = out.replace(dynRe, (_m, pre, q, post) => {
|
|
162
|
+
n++;
|
|
163
|
+
return `${pre}${q}${target}${q}${post}`;
|
|
164
|
+
});
|
|
165
|
+
out = out.replace(reqRe, (_m, pre, q, post) => {
|
|
166
|
+
n++;
|
|
167
|
+
return lib === "aos" ? `${pre}${q}${target}${q}${post}` : `${pre}${q}${target}${q}${post}.default`;
|
|
168
|
+
});
|
|
169
|
+
if (n) changes.push(`${LABEL[lib]}: ${n} import${n === 1 ? "" : "s"} \u2192 ${target}`);
|
|
170
|
+
}
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
function dropAosCssImports(src, changes) {
|
|
174
|
+
let n = 0;
|
|
175
|
+
const out = src.replace(/^[ \t]*import\s+(['"])aos\/dist\/aos(?:\.min)?\.css\1;?[ \t]*\r?\n?/gm, () => {
|
|
176
|
+
n++;
|
|
177
|
+
return "";
|
|
178
|
+
}).replace(/^[ \t]*require\s*\(\s*(['"])aos\/dist\/aos(?:\.min)?\.css\1\s*\);?[ \t]*\r?\n?/gm, () => {
|
|
179
|
+
n++;
|
|
180
|
+
return "";
|
|
181
|
+
});
|
|
182
|
+
if (n) changes.push(`AOS: removed ${n} aos.css import${n === 1 ? "" : "s"} (the drop-in ships its styles)`);
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
var SCRIPT_URL = {
|
|
186
|
+
aos: /^(?:https?:)?\/\/(?:unpkg\.com\/aos(?:@[^/]+)?(?:\/dist\/aos(?:\.min)?\.js)?|cdn\.jsdelivr\.net\/npm\/aos(?:@[^/]+)?(?:\/dist\/aos(?:\.min)?\.js)?|cdnjs\.cloudflare\.com\/ajax\/libs\/aos\/[^/]+\/aos(?:\.min)?\.js)$|(?:^|\/)node_modules\/aos\/dist\/aos(?:\.min)?\.js$/,
|
|
187
|
+
scrollreveal: /^(?:https?:)?\/\/(?:unpkg\.com\/scrollreveal(?:@[^/]+)?(?:\/dist\/scrollreveal(?:\.min)?\.js)?|cdn\.jsdelivr\.net\/npm\/scrollreveal(?:@[^/]+)?(?:\/dist\/scrollreveal(?:\.min)?\.js)?|cdnjs\.cloudflare\.com\/ajax\/libs\/scrollReveal\.js\/[^/]+\/scrollreveal(?:\.min)?\.js)$|(?:^|\/)node_modules\/scrollreveal\/dist\/scrollreveal(?:\.min)?\.js$/i,
|
|
188
|
+
vivus: /^(?:https?:)?\/\/(?:unpkg\.com\/vivus(?:@[^/]+)?(?:\/dist\/vivus(?:\.min)?\.js)?|cdn\.jsdelivr\.net\/npm\/vivus(?:@[^/]+)?(?:\/dist\/vivus(?:\.min)?\.js)?|cdnjs\.cloudflare\.com\/ajax\/libs\/vivus\/[^/]+\/vivus(?:\.min)?\.js)$|(?:^|\/)node_modules\/vivus\/dist\/vivus(?:\.min)?\.js$/
|
|
189
|
+
};
|
|
190
|
+
var AOS_CSS_URL = /^(?:https?:)?\/\/(?:unpkg\.com\/aos(?:@[^/]+)?\/dist\/aos\.css|cdn\.jsdelivr\.net\/npm\/aos(?:@[^/]+)?\/dist\/aos\.css|cdnjs\.cloudflare\.com\/ajax\/libs\/aos\/[^/]+\/aos(?:\.min)?\.css)$|(?:^|\/)node_modules\/aos\/dist\/aos\.css$/;
|
|
191
|
+
function rewriteScriptTags(src, version, changes) {
|
|
192
|
+
return src.replace(/<script\b([^>]*)>/gi, (tag, attrs) => {
|
|
193
|
+
const m = /\bsrc\s*=\s*(["'])([^"']+)\1/i.exec(attrs);
|
|
194
|
+
if (!m) return tag;
|
|
195
|
+
const lib = LIBS.find((l) => SCRIPT_URL[l].test(m[2]));
|
|
196
|
+
if (!lib) return tag;
|
|
197
|
+
const url = `https://unpkg.com/svg-scroll-draw@${version}/dist/cdn/${lib}.global.js`;
|
|
198
|
+
const hadIntegrity = /\bintegrity\s*=/i.test(attrs);
|
|
199
|
+
const next = attrs.replace(m[0], `src=${m[1]}${url}${m[1]}`).replace(/\s+integrity\s*=\s*(["'])[^"']*\1/gi, "");
|
|
200
|
+
changes.push(`${LABEL[lib]}: <script> \u2192 ${url}${hadIntegrity ? " (old integrity hash removed)" : ""}`);
|
|
201
|
+
return `<script${next}>`;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function dropAosCssLinks(src, changes) {
|
|
205
|
+
let n = 0;
|
|
206
|
+
const out = src.replace(/^[ \t]*<link\b[^>]*>[ \t]*\r?\n?/gim, (line) => {
|
|
207
|
+
const m = /\bhref\s*=\s*(["'])([^"']+)\1/i.exec(line);
|
|
208
|
+
if (m && AOS_CSS_URL.test(m[2])) {
|
|
209
|
+
n++;
|
|
210
|
+
return "";
|
|
211
|
+
}
|
|
212
|
+
return line;
|
|
213
|
+
});
|
|
214
|
+
if (n) changes.push(`AOS: removed ${n} aos.css <link> (the drop-in ships its styles)`);
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
function dropAosCssAtImports(src, changes) {
|
|
218
|
+
let n = 0;
|
|
219
|
+
const out = src.replace(
|
|
220
|
+
/^[ \t]*@import\s+(?:url\(\s*)?(['"]?)~?aos\/dist\/aos(?:\.min)?\.css\1\s*\)?\s*;?[ \t]*\r?\n?/gm,
|
|
221
|
+
() => {
|
|
222
|
+
n++;
|
|
223
|
+
return "";
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
if (n) changes.push(`AOS: removed ${n} @import of aos.css (the drop-in ships its styles)`);
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
var SCRIPT_EXT = /\.(?:[cm]?[jt]sx?|vue|svelte|astro)$/i;
|
|
230
|
+
var HTML_EXT = /\.(?:html?|vue|svelte|astro|php|ejs|hbs|njk|liquid|erb)$/i;
|
|
231
|
+
var CSS_EXT = /\.(?:css|scss|sass|less)$/i;
|
|
232
|
+
function migrateSource(src, filename, version) {
|
|
233
|
+
const changes = [];
|
|
234
|
+
let code = src;
|
|
235
|
+
if (SCRIPT_EXT.test(filename)) {
|
|
236
|
+
code = dropAosCssImports(code, changes);
|
|
237
|
+
code = rewriteSpecifiers(code, changes);
|
|
238
|
+
}
|
|
239
|
+
if (HTML_EXT.test(filename)) {
|
|
240
|
+
code = rewriteScriptTags(code, version, changes);
|
|
241
|
+
code = dropAosCssLinks(code, changes);
|
|
242
|
+
}
|
|
243
|
+
if (CSS_EXT.test(filename) || /\.(?:vue|svelte|astro)$/i.test(filename)) {
|
|
244
|
+
code = dropAosCssAtImports(code, changes);
|
|
245
|
+
}
|
|
246
|
+
return { code, changes };
|
|
247
|
+
}
|
|
248
|
+
function migratePackageJson(text, version) {
|
|
249
|
+
const changes = [];
|
|
250
|
+
let pkg;
|
|
251
|
+
try {
|
|
252
|
+
pkg = JSON.parse(text);
|
|
253
|
+
} catch {
|
|
254
|
+
return { code: text, changes };
|
|
255
|
+
}
|
|
256
|
+
const remove = [...LIBS, "@types/aos"];
|
|
257
|
+
let home = null;
|
|
258
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
259
|
+
const deps = pkg[field];
|
|
260
|
+
if (!deps) continue;
|
|
261
|
+
for (const name of remove) {
|
|
262
|
+
if (name in deps) {
|
|
263
|
+
delete deps[name];
|
|
264
|
+
changes.push(`package.json: removed ${name} from ${field}`);
|
|
265
|
+
if (!home && name !== "@types/aos") home = field;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (!home) return { code: text, changes };
|
|
270
|
+
const already = ["dependencies", "devDependencies"].some(
|
|
271
|
+
(f) => pkg[f]?.["svg-scroll-draw"]
|
|
272
|
+
);
|
|
273
|
+
if (!already) {
|
|
274
|
+
const deps = pkg[home] ?? (pkg[home] = {});
|
|
275
|
+
deps["svg-scroll-draw"] = `^${version}`;
|
|
276
|
+
pkg[home] = Object.fromEntries(Object.entries(deps).sort(([a], [b]) => a.localeCompare(b)));
|
|
277
|
+
changes.push(`package.json: added svg-scroll-draw ^${version} to ${home}`);
|
|
278
|
+
}
|
|
279
|
+
const indent = /^\{\r?\n(\t| +)/.exec(text)?.[1] ?? " ";
|
|
280
|
+
return { code: JSON.stringify(pkg, null, indent) + (text.endsWith("\n") ? "\n" : ""), changes };
|
|
281
|
+
}
|
|
282
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
283
|
+
"node_modules",
|
|
284
|
+
".git",
|
|
285
|
+
"dist",
|
|
286
|
+
"build",
|
|
287
|
+
"out",
|
|
288
|
+
".next",
|
|
289
|
+
".nuxt",
|
|
290
|
+
".output",
|
|
291
|
+
".svelte-kit",
|
|
292
|
+
".vercel",
|
|
293
|
+
".netlify",
|
|
294
|
+
".turbo",
|
|
295
|
+
".cache",
|
|
296
|
+
"coverage",
|
|
297
|
+
".parcel-cache",
|
|
298
|
+
"vendor"
|
|
299
|
+
]);
|
|
300
|
+
var MAX_BYTES = 2 * 1024 * 1024;
|
|
301
|
+
function* walk(dir) {
|
|
302
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
303
|
+
if (entry.isDirectory()) {
|
|
304
|
+
if (!SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) yield* walk(path.join(dir, entry.name));
|
|
305
|
+
} else if (entry.isFile()) {
|
|
306
|
+
yield path.join(dir, entry.name);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function installCommand(dir) {
|
|
311
|
+
if (fs.existsSync(path.join(dir, "pnpm-lock.yaml"))) return "pnpm install";
|
|
312
|
+
if (fs.existsSync(path.join(dir, "yarn.lock"))) return "yarn install";
|
|
313
|
+
if (fs.existsSync(path.join(dir, "bun.lockb")) || fs.existsSync(path.join(dir, "bun.lock"))) return "bun install";
|
|
314
|
+
return "npm install";
|
|
315
|
+
}
|
|
316
|
+
function gitDirty(dir) {
|
|
317
|
+
try {
|
|
318
|
+
return (0, import_node_child_process.execSync)("git status --porcelain", { cwd: dir, stdio: ["ignore", "pipe", "ignore"] }).toString().trim() !== "";
|
|
319
|
+
} catch {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
var HELP = `
|
|
324
|
+
svg-scroll-draw migrate [dir] [--dry-run] [--force]
|
|
325
|
+
|
|
326
|
+
Moves a project off AOS, ScrollReveal and vivus onto svg-scroll-draw's drop-ins:
|
|
327
|
+
\u2022 imports / requires of 'aos', 'scrollreveal', 'vivus' \u2192 svg-scroll-draw/<lib>
|
|
328
|
+
\u2022 CDN <script> tags \u2192 svg-scroll-draw's script-tag builds
|
|
329
|
+
\u2022 AOS's aos.css imports, <link>s and @imports removed (the drop-in ships its styles)
|
|
330
|
+
\u2022 package.json: the old packages swapped for svg-scroll-draw
|
|
331
|
+
|
|
332
|
+
--dry-run show what would change, write nothing
|
|
333
|
+
--force write even if the git working tree has uncommitted changes
|
|
334
|
+
`;
|
|
335
|
+
function runMigrate(args, version, log = console.log) {
|
|
336
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
337
|
+
log(HELP);
|
|
338
|
+
return 0;
|
|
339
|
+
}
|
|
340
|
+
const dryRun = args.includes("--dry-run");
|
|
341
|
+
const force = args.includes("--force");
|
|
342
|
+
const dir = path.resolve(args.find((a) => !a.startsWith("-")) ?? ".");
|
|
343
|
+
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) {
|
|
344
|
+
log(` \u2717 Not a directory: ${dir}`);
|
|
345
|
+
return 1;
|
|
346
|
+
}
|
|
347
|
+
const edits = [];
|
|
348
|
+
for (const file of walk(dir)) {
|
|
349
|
+
const base = path.basename(file);
|
|
350
|
+
const isPkg = base === "package.json";
|
|
351
|
+
if (!isPkg && !SCRIPT_EXT.test(base) && !HTML_EXT.test(base) && !CSS_EXT.test(base)) continue;
|
|
352
|
+
if (fs.statSync(file).size > MAX_BYTES) continue;
|
|
353
|
+
const text = fs.readFileSync(file, "utf8");
|
|
354
|
+
if (!isPkg && !/aos|scrollreveal|vivus/i.test(text)) continue;
|
|
355
|
+
const result = isPkg ? migratePackageJson(text, version) : migrateSource(text, base, version);
|
|
356
|
+
if (result.changes.length && result.code !== text) edits.push({ file, code: result.code, changes: result.changes });
|
|
357
|
+
}
|
|
358
|
+
log(`
|
|
359
|
+
svg-scroll-draw migrate${dryRun ? " (dry run)" : ""} \u2014 ${dir}
|
|
360
|
+
`);
|
|
361
|
+
if (!edits.length) {
|
|
362
|
+
log(" No AOS, ScrollReveal or vivus usage found. Nothing to do.\n");
|
|
363
|
+
return 0;
|
|
364
|
+
}
|
|
365
|
+
for (const { file, changes } of edits) {
|
|
366
|
+
log(` ${path.relative(dir, file) || path.basename(file)}`);
|
|
367
|
+
for (const c of changes) log(` \u2022 ${c}`);
|
|
368
|
+
}
|
|
369
|
+
if (dryRun) {
|
|
370
|
+
log(`
|
|
371
|
+
${edits.length} file${edits.length === 1 ? "" : "s"} would change. Run again without --dry-run to apply.
|
|
372
|
+
`);
|
|
373
|
+
return 0;
|
|
374
|
+
}
|
|
375
|
+
if (!force && gitDirty(dir)) {
|
|
376
|
+
log("\n \u2717 The git working tree has uncommitted changes. Commit or stash them first so the");
|
|
377
|
+
log(" migration is a clean diff you can review, or pass --force to write anyway.\n");
|
|
378
|
+
return 1;
|
|
379
|
+
}
|
|
380
|
+
for (const { file, code } of edits) fs.writeFileSync(file, code);
|
|
381
|
+
const touchedPkg = edits.some((e) => path.basename(e.file) === "package.json");
|
|
382
|
+
log(`
|
|
383
|
+
\u2713 Updated ${edits.length} file${edits.length === 1 ? "" : "s"}.`);
|
|
384
|
+
log(` Next: ${touchedPkg ? `run \`${installCommand(dir)}\`, then ` : ""}review the diff (git diff) and try the page.
|
|
385
|
+
`);
|
|
386
|
+
return 0;
|
|
387
|
+
}
|
|
388
|
+
|
|
141
389
|
// src/cli/init.ts
|
|
142
390
|
var RESET = "\x1B[0m";
|
|
143
391
|
var BOLD = "\x1B[1m";
|
|
@@ -147,19 +395,19 @@ var GREEN = "\x1B[32m";
|
|
|
147
395
|
var CYAN = "\x1B[36m";
|
|
148
396
|
function ask(rl, question, fallback) {
|
|
149
397
|
return new Promise(
|
|
150
|
-
(
|
|
151
|
-
|
|
398
|
+
(resolve2) => rl.question(` ${CYAN}?${RESET} ${question} ${DIM}(${fallback})${RESET} `, (ans) => {
|
|
399
|
+
resolve2(ans.trim() || fallback);
|
|
152
400
|
})
|
|
153
401
|
);
|
|
154
402
|
}
|
|
155
403
|
function pick(rl, question, options, fallback) {
|
|
156
404
|
const opts = options.map((o, i) => `${DIM}${i + 1})${RESET} ${o}`).join(" ");
|
|
157
405
|
return new Promise(
|
|
158
|
-
(
|
|
406
|
+
(resolve2) => rl.question(` ${CYAN}?${RESET} ${question}
|
|
159
407
|
${opts}
|
|
160
408
|
${DIM}(${fallback})${RESET} `, (ans) => {
|
|
161
409
|
const idx = parseInt(ans) - 1;
|
|
162
|
-
|
|
410
|
+
resolve2(idx >= 0 && idx < options.length ? options[idx] : fallback);
|
|
163
411
|
})
|
|
164
412
|
);
|
|
165
413
|
}
|
|
@@ -179,8 +427,8 @@ async function main() {
|
|
|
179
427
|
}
|
|
180
428
|
const selector = needsSelector(framework) ? await ask(rl, "CSS selector for your SVG container?", "#my-svg") : "#my-svg";
|
|
181
429
|
const outFile = FILE_NAMES[framework] ?? "scroll-draw.js";
|
|
182
|
-
const outPath =
|
|
183
|
-
if (
|
|
430
|
+
const outPath = path2.join(process.cwd(), outFile);
|
|
431
|
+
if (fs2.existsSync(outPath)) {
|
|
184
432
|
const overwrite = await ask(rl, `${outFile} already exists. Overwrite?`, "y");
|
|
185
433
|
if (overwrite.toLowerCase() !== "y") {
|
|
186
434
|
console.log(`
|
|
@@ -190,7 +438,7 @@ async function main() {
|
|
|
190
438
|
}
|
|
191
439
|
}
|
|
192
440
|
const code = GENERATORS[framework]?.({ selector, easing, preset }) ?? "";
|
|
193
|
-
|
|
441
|
+
fs2.writeFileSync(outPath, code, "utf8");
|
|
194
442
|
console.log(`
|
|
195
443
|
${GREEN}\u2713${RESET} ${BOLD}${outFile}${RESET} created.
|
|
196
444
|
`);
|
|
@@ -208,7 +456,30 @@ async function main() {
|
|
|
208
456
|
rl.close();
|
|
209
457
|
}
|
|
210
458
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
459
|
+
function ownVersion() {
|
|
460
|
+
try {
|
|
461
|
+
return JSON.parse(fs2.readFileSync(path2.join(__dirname, "..", "..", "package.json"), "utf8")).version;
|
|
462
|
+
} catch {
|
|
463
|
+
return "latest";
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
var USAGE = `
|
|
467
|
+
npx svg-scroll-draw init scaffold a starter file
|
|
468
|
+
npx svg-scroll-draw migrate switch a project from AOS, ScrollReveal or vivus (--dry-run to preview)
|
|
469
|
+
`;
|
|
470
|
+
var [command, ...rest] = process.argv.slice(2);
|
|
471
|
+
if (command === "help" || command === "--help" || command === "-h") {
|
|
472
|
+
console.log(USAGE);
|
|
473
|
+
} else if (command === "migrate") {
|
|
474
|
+
process.exitCode = runMigrate(rest, ownVersion());
|
|
475
|
+
} else if (command === void 0 || command === "init") {
|
|
476
|
+
main().catch((e) => {
|
|
477
|
+
console.error(e);
|
|
478
|
+
process.exit(1);
|
|
479
|
+
});
|
|
480
|
+
} else {
|
|
481
|
+
console.error(`
|
|
482
|
+
Unknown command "${command}".
|
|
483
|
+
${USAGE}`);
|
|
484
|
+
process.exitCode = 1;
|
|
485
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});function g(){return typeof window>"u"||typeof window.matchMedia!="function"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches}var w=typeof __SVG_SCROLL_DRAW_DEV__<"u"?__SVG_SCROLL_DRAW_DEV__:typeof process<"u"&&typeof process.env<"u"&&process.env.NODE_ENV!=="production";function m(r,...t){w&&console.warn(`[svg-scroll-draw] ${r}`,...t);}var E=["delayed","sync","async","nsync","oneByOne","scenario","scenario-sync"],L=["inViewport","manual","autostart"];function u(r,t){let e=parseInt(r,10);return e>=0?e:t}function V(r){if(typeof window>"u")return false;let t=window,e=i=>typeof t[i]=="function"&&r instanceof t[i];return e("SVGSVGElement")||e("SVGGElement")||r?.constructor===t.SVGElement}var y=["cx","cy","points","r","rx","ry","x","x1","x2","y","y1","y2"],$=["line","ellipse","circle","polygon","polyline","rect"],x="http://www.w3.org/2000/svg";function v(r){let t=r.points.trim().split(" ");if(r.points.indexOf(",")===-1){let i=[];for(let s=0;s<t.length;s+=2)i.push(`${t[s]},${t[s+1]}`);t=i;}let e=`M${t[0]}`;for(let i=1;i<t.length;i++)t[i].indexOf(",")!==-1&&(e+=`L${t[i]}`);return e}function b(r,t,e,i){let s=parseFloat(e)||0,a=parseFloat(i)||0,n=parseFloat(r)||0,o=parseFloat(t)||0,l=n-s,h=n+s;return `M${l},${o}A${s},${a} 0,1,1 ${h},${o}A${s},${a} 0,1,1 ${l},${o}`}var A={line:r=>`M${r.x1||0},${r.y1||0}L${r.x2||0},${r.y2||0}`,rect(r){let t=parseFloat(r.x)||0,e=parseFloat(r.y)||0,i=parseFloat(r.width)||0,s=parseFloat(r.height)||0;if(r.rx||r.ry){let a=parseInt(r.rx,10)||-1,n=parseInt(r.ry,10)||-1;a=Math.min(Math.max(a<0?n:a,0),i/2),n=Math.min(Math.max(n<0?a:n,0),s/2);let o=`A ${a},${n},0,0,1,`;return `M ${t+a},${e} L ${t+i-a},${e} ${o}${t+i},${e+n} L ${t+i},${e+s-n} ${o}${t+i-a},${e+s} L ${t+a},${e+s} ${o}${t},${e+s-n} L ${t},${e+n} ${o}${t+a},${e}`}return `M${t} ${e} L${t+i} ${e} L${t+i} ${e+s} L${t} ${e+s} Z`},polyline:v,polygon:r=>`${v(r)}Z`,ellipse:r=>b(r.cx,r.cy,r.rx,r.ry),circle:r=>b(r.cx,r.cy,r.r,r.r)};function R(r){for(let t of Array.from(r.querySelectorAll($.join(",")))){let e={};for(let{name:a,value:n}of Array.from(t.attributes)){if(y.indexOf(a)!==-1&&n.indexOf("%")!==-1)throw new Error("Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into 'path' tags. Please use 'viewBox'.");e[a]=n;}let i=A[t.tagName.toLowerCase()](e),s=document.createElementNS(x,"path");for(let{name:a,value:n}of Array.from(t.attributes))y.indexOf(a)===-1&&s.setAttribute(a,n);s.setAttribute("d",i),t.parentNode?.replaceChild(s,t);}}var c=class c{constructor(t,e,i){this.isReady=false;this.type="delayed";this.start="inViewport";this.duration=120;this.delay=null;this.dashGap=1;this.forceRender=false;this.reverseStack=false;this.selfDestroy=false;this.ignoreInvisible=false;this.animTimingFunction=c.LINEAR;this.pathTimingFunction=c.LINEAR;this.callback=()=>{};this.map=[];this.frameLength=0;this.currentFrame=0;this.delayUnit=0;this.speed=1;this.handle=null;this.instanceCallback=null;this.mustRecalcScale=null;this.viewportListener=null;this.setElement(t,e),this.setOptions(e),this.setCallback(i),this.isReady&&this.init();}setElement(t,e){if(t===void 0)throw new Error('Vivus [constructor]: "element" parameter is required');let i=t;if(typeof i=="string"){let s=document.getElementById(i);if(!s)throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');i=s;}if(this.parentEl=i,e&&e.file){let s=new XMLHttpRequest;s.addEventListener("load",()=>{let a=document.createElement("div");a.innerHTML=s.responseText;let n=a.querySelector("svg");if(!n)throw new Error(`Vivus [load]: Cannot find the SVG in the loaded file : ${e.file}`);this.el=n,n.setAttribute("width","100%"),n.setAttribute("height","100%"),this.parentEl.appendChild(n),this.isReady=true,this.init();}),s.open("GET",e.file),s.send();return}if(V(i)){this.el=i,this.isReady=true;return}if(i instanceof HTMLObjectElement){let s=i,a=n=>{if(this.isReady)return;let o=s.contentDocument&&s.contentDocument.querySelector("svg");if(!o&&n)throw new Error("Vivus [constructor]: object loaded does not contain any SVG");o&&(s.getAttribute("built-by-vivus")&&(this.parentEl.insertBefore(o,s),this.parentEl.removeChild(s),o.setAttribute("width","100%"),o.setAttribute("height","100%")),this.el=o,this.isReady=true,this.init());};a(),this.isReady||s.addEventListener("load",a);return}throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)')}setOptions(t){if(t!==void 0&&(t===null||t.constructor!==Object))throw new Error('Vivus [constructor]: "options" parameter must be an object');let e=t||{};if(e.type&&E.indexOf(e.type)===-1)throw new Error(`Vivus [constructor]: ${e.type} is not an existing animation \`type\``);if(e.start&&L.indexOf(e.start)===-1)throw new Error(`Vivus [constructor]: ${e.start} is not an existing \`start\` option`);this.type=e.type||"delayed",this.start=e.start||"inViewport";let i=navigator.userAgent,s=i.indexOf("MSIE")!==-1||i.indexOf("Trident/")!==-1||i.indexOf("Edge/")!==-1;if(this.duration=u(e.duration,120),this.delay=u(e.delay,null),this.dashGap=u(e.dashGap,1),this.forceRender=Object.prototype.hasOwnProperty.call(e,"forceRender")?!!e.forceRender:s,this.reverseStack=!!e.reverseStack,this.selfDestroy=!!e.selfDestroy,this.onReady=e.onReady,this.map=[],this.ignoreInvisible=Object.prototype.hasOwnProperty.call(e,"ignoreInvisible")?!!e.ignoreInvisible:false,this.animTimingFunction=e.animTimingFunction||c.LINEAR,this.pathTimingFunction=e.pathTimingFunction||c.LINEAR,this.delay!==null&&this.delay>=this.duration)throw new Error("Vivus [constructor]: delay must be shorter than duration")}setCallback(t){if(t&&typeof t!="function")throw new Error('Vivus [constructor]: "callback" parameter must be a function');this.callback=t||(()=>{});}mapping(){let t=0,e=0,i=0,s=false,a=Array.from(this.el.querySelectorAll("path"));a.forEach((n,o)=>{if(this.isInvisible(n))return;let l={el:n,length:0,startAt:0,duration:0,isResizeSensitive:false},h=1;if(n.getAttribute("vector-effect")==="non-scaling-stroke"){let d=n.getBoundingClientRect(),f=n.getBBox();h=Math.max(d.width/f.width,d.height/f.height),l.isResizeSensitive=true,s=true;}if(l.length=Math.ceil(n.getTotalLength()*h),isNaN(l.length)){m("vivus: cannot retrieve a path element length",n);return}this.map.push(l),n.style.strokeDasharray=`${l.length} ${l.length+this.dashGap*2}`,n.style.strokeDashoffset=String(l.length+this.dashGap),l.length+=this.dashGap,e+=l.length,this.renderPath(o);}),s&&m("vivus: this SVG contains non-scaling-strokes. Call instance.recalc() when the SVG is resized."),e=e===0?1:e,this.delay=this.delay===null?this.duration/3:this.delay,this.delayUnit=this.delay/(a.length>1?a.length-1:1),this.reverseStack&&this.map.reverse(),this.map.forEach((n,o)=>{let l=()=>{let h={};for(let{name:d,value:f}of Array.from(n.el.attributes))h[d]=f;return h};switch(this.type){case "delayed":n.startAt=this.delayUnit*o,n.duration=this.duration-this.delay;break;case "oneByOne":n.startAt=i/e*this.duration,n.duration=n.length/e*this.duration;break;case "sync":case "async":case "nsync":n.startAt=0,n.duration=this.duration;break;case "scenario-sync":{let h=l();n.startAt=t+(u(h["data-delay"],this.delayUnit)||0),n.duration=u(h["data-duration"],this.duration),t=h["data-async"]!==void 0?n.startAt:n.startAt+n.duration,this.frameLength=Math.max(this.frameLength,n.startAt+n.duration);break}case "scenario":{let h=l();n.startAt=u(h["data-start"],this.delayUnit)||0,n.duration=u(h["data-duration"],this.duration),this.frameLength=Math.max(this.frameLength,n.startAt+n.duration);break}}i+=n.length,this.frameLength=this.frameLength||this.duration;});}recalc(){this.mustRecalcScale||(this.mustRecalcScale=requestAnimationFrame(()=>this.performLineRecalc()));}performLineRecalc(){for(let t of this.map){if(!t.isResizeSensitive)continue;let e=t.el.getBoundingClientRect(),i=t.el.getBBox(),s=Math.max(e.width/i.width,e.height/i.height);t.length=Math.ceil(t.el.getTotalLength()*s),t.el.style.strokeDasharray=`${t.length} ${t.length+this.dashGap*2}`;}this.trace(),this.mustRecalcScale=null;}draw(){if(this.currentFrame+=this.speed,this.currentFrame<=0)this.stop(),this.reset();else if(this.currentFrame>=this.frameLength)this.stop(),this.currentFrame=this.frameLength,this.trace(),this.selfDestroy&&this.destroy();else {this.trace(),this.handle=requestAnimationFrame(()=>this.draw());return}this.finished();}finished(){if(this.callback(this),this.instanceCallback){let t=this.instanceCallback;this.instanceCallback=null,t(this);}}trace(){let t=this.animTimingFunction(this.currentFrame/this.frameLength)*this.frameLength;this.map.forEach((e,i)=>{let s=this.pathTimingFunction(Math.max(0,Math.min(1,(t-e.startAt)/e.duration)));e.progress!==s&&(e.progress=s,e.el.style.strokeDashoffset=String(Math.floor(e.length*(1-s))),this.renderPath(i));});}renderPath(t){let e=this.forceRender&&this.map&&this.map[t];if(!e)return;let i=e.el.cloneNode(true);e.el.parentNode?.replaceChild(i,e.el),e.el=i;}init(){this.frameLength=0,this.currentFrame=0,this.map=[],R(this.el),this.mapping(),this.starter(),this.onReady&&this.onReady(this);}starter(){if(this.start==="manual")return;if(this.start==="autostart"){this.play();return}let t=()=>{this.isInViewport(this.parentEl,1)&&(this.play(),window.removeEventListener("scroll",t),this.viewportListener=null);};this.viewportListener=t,window.addEventListener("scroll",t),t();}getStatus(){return this.currentFrame===0?"start":this.currentFrame===this.frameLength?"end":"progress"}reset(){return this.setFrameProgress(0)}finish(){return this.setFrameProgress(1)}setFrameProgress(t){let e=Math.min(1,Math.max(0,t));return this.currentFrame=Math.round(this.frameLength*e),this.trace(),this}play(t,e){this.instanceCallback=null;let i=t;if(i&&typeof i=="function")this.instanceCallback=i,i=void 0;else if(i&&typeof i!="number")throw new Error("Vivus [play]: invalid speed");return e&&typeof e=="function"&&!this.instanceCallback&&(this.instanceCallback=e),this.speed=i||1,g()?(this.stop(),this.currentFrame=this.speed<0?0:this.frameLength,this.trace(),this.speed>0&&this.selfDestroy&&this.destroy(),this.finished(),this):(this.handle||this.draw(),this)}stop(){return this.handle&&(cancelAnimationFrame(this.handle),this.handle=null),this}destroy(){this.stop(),this.viewportListener&&(window.removeEventListener("scroll",this.viewportListener),this.viewportListener=null),this.map.forEach((t,e)=>{t.el.style.strokeDashoffset="",t.el.style.strokeDasharray="",this.renderPath(e);});}isInvisible(t){let e=t.getAttribute("data-ignore");if(e!==null)return e!=="false";if(this.ignoreInvisible){let i=t.getBoundingClientRect();return !i.width&&!i.height}return false}isInViewport(t,e=0){let i=window.pageYOffset||document.documentElement.scrollTop,s=i+Math.max(document.documentElement.clientHeight,window.innerHeight),a=t.getBoundingClientRect(),n=i+a.top;return n+a.height*(e||0)<=s&&n+a.height>=i}};c.LINEAR=t=>t,c.EASE=t=>-Math.cos(t*Math.PI)/2+.5,c.EASE_OUT=t=>1-Math.pow(1-t,3),c.EASE_IN=t=>Math.pow(t,3),c.EASE_OUT_BOUNCE=t=>{let e=-Math.cos(t*(.5*Math.PI))+1,i=Math.pow(e,1.5),s=Math.pow(1-t,2),a=-Math.abs(Math.cos(i*(2.5*Math.PI)))+1;return 1-s+a*s};var p=c,O=p;
|
|
2
|
+
exports.Vivus=p;exports.default=O;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
type VivusType = 'delayed' | 'sync' | 'async' | 'nsync' | 'oneByOne' | 'scenario' | 'scenario-sync';
|
|
2
|
+
type VivusStart = 'inViewport' | 'manual' | 'autostart';
|
|
3
|
+
type VivusTiming = (x: number) => number;
|
|
4
|
+
type VivusCallback = (instance: Vivus) => void;
|
|
5
|
+
interface VivusOptions {
|
|
6
|
+
type?: VivusType;
|
|
7
|
+
/** Load the SVG from this URL into `element` instead of using markup. */
|
|
8
|
+
file?: string;
|
|
9
|
+
start?: VivusStart;
|
|
10
|
+
/** Animation length in frames. Default 120. */
|
|
11
|
+
duration?: number;
|
|
12
|
+
/** For `delayed`: frames between the first and last path starting. Default duration / 3. */
|
|
13
|
+
delay?: number;
|
|
14
|
+
/** Extra gap in the dash pattern, so the line start never shows early. Default 1. */
|
|
15
|
+
dashGap?: number;
|
|
16
|
+
/** Clone-and-replace each path after every update (an old IE/Edge repaint hack). */
|
|
17
|
+
forceRender?: boolean;
|
|
18
|
+
reverseStack?: boolean;
|
|
19
|
+
selfDestroy?: boolean;
|
|
20
|
+
onReady?: VivusCallback;
|
|
21
|
+
ignoreInvisible?: boolean;
|
|
22
|
+
pathTimingFunction?: VivusTiming;
|
|
23
|
+
animTimingFunction?: VivusTiming;
|
|
24
|
+
}
|
|
25
|
+
interface PathRecord {
|
|
26
|
+
el: SVGPathElement;
|
|
27
|
+
length: number;
|
|
28
|
+
startAt: number;
|
|
29
|
+
duration: number;
|
|
30
|
+
isResizeSensitive: boolean;
|
|
31
|
+
progress?: number;
|
|
32
|
+
}
|
|
33
|
+
declare class Vivus {
|
|
34
|
+
static LINEAR: VivusTiming;
|
|
35
|
+
static EASE: VivusTiming;
|
|
36
|
+
static EASE_OUT: VivusTiming;
|
|
37
|
+
static EASE_IN: VivusTiming;
|
|
38
|
+
static EASE_OUT_BOUNCE: VivusTiming;
|
|
39
|
+
el: Element;
|
|
40
|
+
parentEl: Element;
|
|
41
|
+
isReady: boolean;
|
|
42
|
+
type: VivusType;
|
|
43
|
+
start: VivusStart;
|
|
44
|
+
duration: number;
|
|
45
|
+
delay: number | null;
|
|
46
|
+
dashGap: number;
|
|
47
|
+
forceRender: boolean;
|
|
48
|
+
reverseStack: boolean;
|
|
49
|
+
selfDestroy: boolean;
|
|
50
|
+
ignoreInvisible: boolean;
|
|
51
|
+
onReady?: VivusCallback;
|
|
52
|
+
animTimingFunction: VivusTiming;
|
|
53
|
+
pathTimingFunction: VivusTiming;
|
|
54
|
+
callback: VivusCallback;
|
|
55
|
+
map: PathRecord[];
|
|
56
|
+
frameLength: number;
|
|
57
|
+
currentFrame: number;
|
|
58
|
+
delayUnit: number;
|
|
59
|
+
speed: number;
|
|
60
|
+
handle: number | null;
|
|
61
|
+
private instanceCallback;
|
|
62
|
+
private mustRecalcScale;
|
|
63
|
+
private viewportListener;
|
|
64
|
+
constructor(element: string | Element, options?: VivusOptions, callback?: VivusCallback);
|
|
65
|
+
private setElement;
|
|
66
|
+
private setOptions;
|
|
67
|
+
private setCallback;
|
|
68
|
+
/** Measure every path, set its dashes, and work out when each one draws. */
|
|
69
|
+
mapping(): void;
|
|
70
|
+
/** Re-measure `vector-effect: non-scaling-stroke` paths on the next frame (after a resize). */
|
|
71
|
+
recalc(): void;
|
|
72
|
+
performLineRecalc(): void;
|
|
73
|
+
/** One frame: advance by `speed`, render, and finish at either end. */
|
|
74
|
+
draw(): void;
|
|
75
|
+
private finished;
|
|
76
|
+
/** Render the current frame to every path's dash offset. */
|
|
77
|
+
trace(): void;
|
|
78
|
+
renderPath(index: number): void;
|
|
79
|
+
init(): void;
|
|
80
|
+
private starter;
|
|
81
|
+
/** `'start'`, `'progress'` or `'end'`. */
|
|
82
|
+
getStatus(): 'start' | 'progress' | 'end';
|
|
83
|
+
reset(): this;
|
|
84
|
+
finish(): this;
|
|
85
|
+
/** Jump to a point (0–1) and render it. */
|
|
86
|
+
setFrameProgress(progress: number): this;
|
|
87
|
+
/**
|
|
88
|
+
* Animate at `speed` frames per frame (negative plays backwards). The callback
|
|
89
|
+
* may be given alone, as the first argument.
|
|
90
|
+
*/
|
|
91
|
+
play(speed?: number | VivusCallback, callback?: VivusCallback): this;
|
|
92
|
+
stop(): this;
|
|
93
|
+
/** Stop and remove every dash style vivus set. */
|
|
94
|
+
destroy(): void;
|
|
95
|
+
isInvisible(el: Element): boolean;
|
|
96
|
+
/** Whether `el` is in view; with `h` = 1 its whole height must fit above the fold. */
|
|
97
|
+
isInViewport(el: Element, h?: number): boolean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export { Vivus, type VivusCallback, type VivusOptions, type VivusStart, type VivusTiming, type VivusType, Vivus as default };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
type VivusType = 'delayed' | 'sync' | 'async' | 'nsync' | 'oneByOne' | 'scenario' | 'scenario-sync';
|
|
2
|
+
type VivusStart = 'inViewport' | 'manual' | 'autostart';
|
|
3
|
+
type VivusTiming = (x: number) => number;
|
|
4
|
+
type VivusCallback = (instance: Vivus) => void;
|
|
5
|
+
interface VivusOptions {
|
|
6
|
+
type?: VivusType;
|
|
7
|
+
/** Load the SVG from this URL into `element` instead of using markup. */
|
|
8
|
+
file?: string;
|
|
9
|
+
start?: VivusStart;
|
|
10
|
+
/** Animation length in frames. Default 120. */
|
|
11
|
+
duration?: number;
|
|
12
|
+
/** For `delayed`: frames between the first and last path starting. Default duration / 3. */
|
|
13
|
+
delay?: number;
|
|
14
|
+
/** Extra gap in the dash pattern, so the line start never shows early. Default 1. */
|
|
15
|
+
dashGap?: number;
|
|
16
|
+
/** Clone-and-replace each path after every update (an old IE/Edge repaint hack). */
|
|
17
|
+
forceRender?: boolean;
|
|
18
|
+
reverseStack?: boolean;
|
|
19
|
+
selfDestroy?: boolean;
|
|
20
|
+
onReady?: VivusCallback;
|
|
21
|
+
ignoreInvisible?: boolean;
|
|
22
|
+
pathTimingFunction?: VivusTiming;
|
|
23
|
+
animTimingFunction?: VivusTiming;
|
|
24
|
+
}
|
|
25
|
+
interface PathRecord {
|
|
26
|
+
el: SVGPathElement;
|
|
27
|
+
length: number;
|
|
28
|
+
startAt: number;
|
|
29
|
+
duration: number;
|
|
30
|
+
isResizeSensitive: boolean;
|
|
31
|
+
progress?: number;
|
|
32
|
+
}
|
|
33
|
+
declare class Vivus {
|
|
34
|
+
static LINEAR: VivusTiming;
|
|
35
|
+
static EASE: VivusTiming;
|
|
36
|
+
static EASE_OUT: VivusTiming;
|
|
37
|
+
static EASE_IN: VivusTiming;
|
|
38
|
+
static EASE_OUT_BOUNCE: VivusTiming;
|
|
39
|
+
el: Element;
|
|
40
|
+
parentEl: Element;
|
|
41
|
+
isReady: boolean;
|
|
42
|
+
type: VivusType;
|
|
43
|
+
start: VivusStart;
|
|
44
|
+
duration: number;
|
|
45
|
+
delay: number | null;
|
|
46
|
+
dashGap: number;
|
|
47
|
+
forceRender: boolean;
|
|
48
|
+
reverseStack: boolean;
|
|
49
|
+
selfDestroy: boolean;
|
|
50
|
+
ignoreInvisible: boolean;
|
|
51
|
+
onReady?: VivusCallback;
|
|
52
|
+
animTimingFunction: VivusTiming;
|
|
53
|
+
pathTimingFunction: VivusTiming;
|
|
54
|
+
callback: VivusCallback;
|
|
55
|
+
map: PathRecord[];
|
|
56
|
+
frameLength: number;
|
|
57
|
+
currentFrame: number;
|
|
58
|
+
delayUnit: number;
|
|
59
|
+
speed: number;
|
|
60
|
+
handle: number | null;
|
|
61
|
+
private instanceCallback;
|
|
62
|
+
private mustRecalcScale;
|
|
63
|
+
private viewportListener;
|
|
64
|
+
constructor(element: string | Element, options?: VivusOptions, callback?: VivusCallback);
|
|
65
|
+
private setElement;
|
|
66
|
+
private setOptions;
|
|
67
|
+
private setCallback;
|
|
68
|
+
/** Measure every path, set its dashes, and work out when each one draws. */
|
|
69
|
+
mapping(): void;
|
|
70
|
+
/** Re-measure `vector-effect: non-scaling-stroke` paths on the next frame (after a resize). */
|
|
71
|
+
recalc(): void;
|
|
72
|
+
performLineRecalc(): void;
|
|
73
|
+
/** One frame: advance by `speed`, render, and finish at either end. */
|
|
74
|
+
draw(): void;
|
|
75
|
+
private finished;
|
|
76
|
+
/** Render the current frame to every path's dash offset. */
|
|
77
|
+
trace(): void;
|
|
78
|
+
renderPath(index: number): void;
|
|
79
|
+
init(): void;
|
|
80
|
+
private starter;
|
|
81
|
+
/** `'start'`, `'progress'` or `'end'`. */
|
|
82
|
+
getStatus(): 'start' | 'progress' | 'end';
|
|
83
|
+
reset(): this;
|
|
84
|
+
finish(): this;
|
|
85
|
+
/** Jump to a point (0–1) and render it. */
|
|
86
|
+
setFrameProgress(progress: number): this;
|
|
87
|
+
/**
|
|
88
|
+
* Animate at `speed` frames per frame (negative plays backwards). The callback
|
|
89
|
+
* may be given alone, as the first argument.
|
|
90
|
+
*/
|
|
91
|
+
play(speed?: number | VivusCallback, callback?: VivusCallback): this;
|
|
92
|
+
stop(): this;
|
|
93
|
+
/** Stop and remove every dash style vivus set. */
|
|
94
|
+
destroy(): void;
|
|
95
|
+
isInvisible(el: Element): boolean;
|
|
96
|
+
/** Whether `el` is in view; with `h` = 1 its whole height must fit above the fold. */
|
|
97
|
+
isInViewport(el: Element, h?: number): boolean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export { Vivus, type VivusCallback, type VivusOptions, type VivusStart, type VivusTiming, type VivusType, Vivus as default };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function g(){return typeof window>"u"||typeof window.matchMedia!="function"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches}var w=typeof __SVG_SCROLL_DRAW_DEV__<"u"?__SVG_SCROLL_DRAW_DEV__:typeof process<"u"&&typeof process.env<"u"&&process.env.NODE_ENV!=="production";function m(r,...t){w&&console.warn(`[svg-scroll-draw] ${r}`,...t);}var E=["delayed","sync","async","nsync","oneByOne","scenario","scenario-sync"],L=["inViewport","manual","autostart"];function u(r,t){let e=parseInt(r,10);return e>=0?e:t}function V(r){if(typeof window>"u")return false;let t=window,e=i=>typeof t[i]=="function"&&r instanceof t[i];return e("SVGSVGElement")||e("SVGGElement")||r?.constructor===t.SVGElement}var y=["cx","cy","points","r","rx","ry","x","x1","x2","y","y1","y2"],$=["line","ellipse","circle","polygon","polyline","rect"],x="http://www.w3.org/2000/svg";function v(r){let t=r.points.trim().split(" ");if(r.points.indexOf(",")===-1){let i=[];for(let s=0;s<t.length;s+=2)i.push(`${t[s]},${t[s+1]}`);t=i;}let e=`M${t[0]}`;for(let i=1;i<t.length;i++)t[i].indexOf(",")!==-1&&(e+=`L${t[i]}`);return e}function b(r,t,e,i){let s=parseFloat(e)||0,a=parseFloat(i)||0,n=parseFloat(r)||0,o=parseFloat(t)||0,l=n-s,h=n+s;return `M${l},${o}A${s},${a} 0,1,1 ${h},${o}A${s},${a} 0,1,1 ${l},${o}`}var A={line:r=>`M${r.x1||0},${r.y1||0}L${r.x2||0},${r.y2||0}`,rect(r){let t=parseFloat(r.x)||0,e=parseFloat(r.y)||0,i=parseFloat(r.width)||0,s=parseFloat(r.height)||0;if(r.rx||r.ry){let a=parseInt(r.rx,10)||-1,n=parseInt(r.ry,10)||-1;a=Math.min(Math.max(a<0?n:a,0),i/2),n=Math.min(Math.max(n<0?a:n,0),s/2);let o=`A ${a},${n},0,0,1,`;return `M ${t+a},${e} L ${t+i-a},${e} ${o}${t+i},${e+n} L ${t+i},${e+s-n} ${o}${t+i-a},${e+s} L ${t+a},${e+s} ${o}${t},${e+s-n} L ${t},${e+n} ${o}${t+a},${e}`}return `M${t} ${e} L${t+i} ${e} L${t+i} ${e+s} L${t} ${e+s} Z`},polyline:v,polygon:r=>`${v(r)}Z`,ellipse:r=>b(r.cx,r.cy,r.rx,r.ry),circle:r=>b(r.cx,r.cy,r.r,r.r)};function R(r){for(let t of Array.from(r.querySelectorAll($.join(",")))){let e={};for(let{name:a,value:n}of Array.from(t.attributes)){if(y.indexOf(a)!==-1&&n.indexOf("%")!==-1)throw new Error("Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into 'path' tags. Please use 'viewBox'.");e[a]=n;}let i=A[t.tagName.toLowerCase()](e),s=document.createElementNS(x,"path");for(let{name:a,value:n}of Array.from(t.attributes))y.indexOf(a)===-1&&s.setAttribute(a,n);s.setAttribute("d",i),t.parentNode?.replaceChild(s,t);}}var c=class c{constructor(t,e,i){this.isReady=false;this.type="delayed";this.start="inViewport";this.duration=120;this.delay=null;this.dashGap=1;this.forceRender=false;this.reverseStack=false;this.selfDestroy=false;this.ignoreInvisible=false;this.animTimingFunction=c.LINEAR;this.pathTimingFunction=c.LINEAR;this.callback=()=>{};this.map=[];this.frameLength=0;this.currentFrame=0;this.delayUnit=0;this.speed=1;this.handle=null;this.instanceCallback=null;this.mustRecalcScale=null;this.viewportListener=null;this.setElement(t,e),this.setOptions(e),this.setCallback(i),this.isReady&&this.init();}setElement(t,e){if(t===void 0)throw new Error('Vivus [constructor]: "element" parameter is required');let i=t;if(typeof i=="string"){let s=document.getElementById(i);if(!s)throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');i=s;}if(this.parentEl=i,e&&e.file){let s=new XMLHttpRequest;s.addEventListener("load",()=>{let a=document.createElement("div");a.innerHTML=s.responseText;let n=a.querySelector("svg");if(!n)throw new Error(`Vivus [load]: Cannot find the SVG in the loaded file : ${e.file}`);this.el=n,n.setAttribute("width","100%"),n.setAttribute("height","100%"),this.parentEl.appendChild(n),this.isReady=true,this.init();}),s.open("GET",e.file),s.send();return}if(V(i)){this.el=i,this.isReady=true;return}if(i instanceof HTMLObjectElement){let s=i,a=n=>{if(this.isReady)return;let o=s.contentDocument&&s.contentDocument.querySelector("svg");if(!o&&n)throw new Error("Vivus [constructor]: object loaded does not contain any SVG");o&&(s.getAttribute("built-by-vivus")&&(this.parentEl.insertBefore(o,s),this.parentEl.removeChild(s),o.setAttribute("width","100%"),o.setAttribute("height","100%")),this.el=o,this.isReady=true,this.init());};a(),this.isReady||s.addEventListener("load",a);return}throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)')}setOptions(t){if(t!==void 0&&(t===null||t.constructor!==Object))throw new Error('Vivus [constructor]: "options" parameter must be an object');let e=t||{};if(e.type&&E.indexOf(e.type)===-1)throw new Error(`Vivus [constructor]: ${e.type} is not an existing animation \`type\``);if(e.start&&L.indexOf(e.start)===-1)throw new Error(`Vivus [constructor]: ${e.start} is not an existing \`start\` option`);this.type=e.type||"delayed",this.start=e.start||"inViewport";let i=navigator.userAgent,s=i.indexOf("MSIE")!==-1||i.indexOf("Trident/")!==-1||i.indexOf("Edge/")!==-1;if(this.duration=u(e.duration,120),this.delay=u(e.delay,null),this.dashGap=u(e.dashGap,1),this.forceRender=Object.prototype.hasOwnProperty.call(e,"forceRender")?!!e.forceRender:s,this.reverseStack=!!e.reverseStack,this.selfDestroy=!!e.selfDestroy,this.onReady=e.onReady,this.map=[],this.ignoreInvisible=Object.prototype.hasOwnProperty.call(e,"ignoreInvisible")?!!e.ignoreInvisible:false,this.animTimingFunction=e.animTimingFunction||c.LINEAR,this.pathTimingFunction=e.pathTimingFunction||c.LINEAR,this.delay!==null&&this.delay>=this.duration)throw new Error("Vivus [constructor]: delay must be shorter than duration")}setCallback(t){if(t&&typeof t!="function")throw new Error('Vivus [constructor]: "callback" parameter must be a function');this.callback=t||(()=>{});}mapping(){let t=0,e=0,i=0,s=false,a=Array.from(this.el.querySelectorAll("path"));a.forEach((n,o)=>{if(this.isInvisible(n))return;let l={el:n,length:0,startAt:0,duration:0,isResizeSensitive:false},h=1;if(n.getAttribute("vector-effect")==="non-scaling-stroke"){let d=n.getBoundingClientRect(),f=n.getBBox();h=Math.max(d.width/f.width,d.height/f.height),l.isResizeSensitive=true,s=true;}if(l.length=Math.ceil(n.getTotalLength()*h),isNaN(l.length)){m("vivus: cannot retrieve a path element length",n);return}this.map.push(l),n.style.strokeDasharray=`${l.length} ${l.length+this.dashGap*2}`,n.style.strokeDashoffset=String(l.length+this.dashGap),l.length+=this.dashGap,e+=l.length,this.renderPath(o);}),s&&m("vivus: this SVG contains non-scaling-strokes. Call instance.recalc() when the SVG is resized."),e=e===0?1:e,this.delay=this.delay===null?this.duration/3:this.delay,this.delayUnit=this.delay/(a.length>1?a.length-1:1),this.reverseStack&&this.map.reverse(),this.map.forEach((n,o)=>{let l=()=>{let h={};for(let{name:d,value:f}of Array.from(n.el.attributes))h[d]=f;return h};switch(this.type){case "delayed":n.startAt=this.delayUnit*o,n.duration=this.duration-this.delay;break;case "oneByOne":n.startAt=i/e*this.duration,n.duration=n.length/e*this.duration;break;case "sync":case "async":case "nsync":n.startAt=0,n.duration=this.duration;break;case "scenario-sync":{let h=l();n.startAt=t+(u(h["data-delay"],this.delayUnit)||0),n.duration=u(h["data-duration"],this.duration),t=h["data-async"]!==void 0?n.startAt:n.startAt+n.duration,this.frameLength=Math.max(this.frameLength,n.startAt+n.duration);break}case "scenario":{let h=l();n.startAt=u(h["data-start"],this.delayUnit)||0,n.duration=u(h["data-duration"],this.duration),this.frameLength=Math.max(this.frameLength,n.startAt+n.duration);break}}i+=n.length,this.frameLength=this.frameLength||this.duration;});}recalc(){this.mustRecalcScale||(this.mustRecalcScale=requestAnimationFrame(()=>this.performLineRecalc()));}performLineRecalc(){for(let t of this.map){if(!t.isResizeSensitive)continue;let e=t.el.getBoundingClientRect(),i=t.el.getBBox(),s=Math.max(e.width/i.width,e.height/i.height);t.length=Math.ceil(t.el.getTotalLength()*s),t.el.style.strokeDasharray=`${t.length} ${t.length+this.dashGap*2}`;}this.trace(),this.mustRecalcScale=null;}draw(){if(this.currentFrame+=this.speed,this.currentFrame<=0)this.stop(),this.reset();else if(this.currentFrame>=this.frameLength)this.stop(),this.currentFrame=this.frameLength,this.trace(),this.selfDestroy&&this.destroy();else {this.trace(),this.handle=requestAnimationFrame(()=>this.draw());return}this.finished();}finished(){if(this.callback(this),this.instanceCallback){let t=this.instanceCallback;this.instanceCallback=null,t(this);}}trace(){let t=this.animTimingFunction(this.currentFrame/this.frameLength)*this.frameLength;this.map.forEach((e,i)=>{let s=this.pathTimingFunction(Math.max(0,Math.min(1,(t-e.startAt)/e.duration)));e.progress!==s&&(e.progress=s,e.el.style.strokeDashoffset=String(Math.floor(e.length*(1-s))),this.renderPath(i));});}renderPath(t){let e=this.forceRender&&this.map&&this.map[t];if(!e)return;let i=e.el.cloneNode(true);e.el.parentNode?.replaceChild(i,e.el),e.el=i;}init(){this.frameLength=0,this.currentFrame=0,this.map=[],R(this.el),this.mapping(),this.starter(),this.onReady&&this.onReady(this);}starter(){if(this.start==="manual")return;if(this.start==="autostart"){this.play();return}let t=()=>{this.isInViewport(this.parentEl,1)&&(this.play(),window.removeEventListener("scroll",t),this.viewportListener=null);};this.viewportListener=t,window.addEventListener("scroll",t),t();}getStatus(){return this.currentFrame===0?"start":this.currentFrame===this.frameLength?"end":"progress"}reset(){return this.setFrameProgress(0)}finish(){return this.setFrameProgress(1)}setFrameProgress(t){let e=Math.min(1,Math.max(0,t));return this.currentFrame=Math.round(this.frameLength*e),this.trace(),this}play(t,e){this.instanceCallback=null;let i=t;if(i&&typeof i=="function")this.instanceCallback=i,i=void 0;else if(i&&typeof i!="number")throw new Error("Vivus [play]: invalid speed");return e&&typeof e=="function"&&!this.instanceCallback&&(this.instanceCallback=e),this.speed=i||1,g()?(this.stop(),this.currentFrame=this.speed<0?0:this.frameLength,this.trace(),this.speed>0&&this.selfDestroy&&this.destroy(),this.finished(),this):(this.handle||this.draw(),this)}stop(){return this.handle&&(cancelAnimationFrame(this.handle),this.handle=null),this}destroy(){this.stop(),this.viewportListener&&(window.removeEventListener("scroll",this.viewportListener),this.viewportListener=null),this.map.forEach((t,e)=>{t.el.style.strokeDashoffset="",t.el.style.strokeDasharray="",this.renderPath(e);});}isInvisible(t){let e=t.getAttribute("data-ignore");if(e!==null)return e!=="false";if(this.ignoreInvisible){let i=t.getBoundingClientRect();return !i.width&&!i.height}return false}isInViewport(t,e=0){let i=window.pageYOffset||document.documentElement.scrollTop,s=i+Math.max(document.documentElement.clientHeight,window.innerHeight),a=t.getBoundingClientRect(),n=i+a.top;return n+a.height*(e||0)<=s&&n+a.height>=i}};c.LINEAR=t=>t,c.EASE=t=>-Math.cos(t*Math.PI)/2+.5,c.EASE_OUT=t=>1-Math.pow(1-t,3),c.EASE_IN=t=>Math.pow(t,3),c.EASE_OUT_BOUNCE=t=>{let e=-Math.cos(t*(.5*Math.PI))+1,i=Math.pow(e,1.5),s=Math.pow(1-t,2),a=-Math.abs(Math.cos(i*(2.5*Math.PI)))+1;return 1-s+a*s};var p=c,O=p;
|
|
2
|
+
export{p as Vivus,O as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svg-scroll-draw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "Scroll-driven animation for the web — draw SVG paths, reveal elements, pin sections, scrub video. Zero dependencies, native CSS fast path, works with React, Vue, Svelte, Solid, Angular, Astro and vanilla JS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"svg",
|
|
@@ -62,7 +62,11 @@
|
|
|
62
62
|
"data-aos",
|
|
63
63
|
"scrollreveal",
|
|
64
64
|
"scrollreveal-alternative",
|
|
65
|
-
"scroll-reveal-mit"
|
|
65
|
+
"scroll-reveal-mit",
|
|
66
|
+
"vivus",
|
|
67
|
+
"vivus-alternative",
|
|
68
|
+
"svg-line-drawing",
|
|
69
|
+
"line-drawing"
|
|
66
70
|
],
|
|
67
71
|
"homepage": "https://svg-scroll-draw.vercel.app",
|
|
68
72
|
"repository": {
|
|
@@ -151,6 +155,9 @@
|
|
|
151
155
|
],
|
|
152
156
|
"scrollreveal": [
|
|
153
157
|
"./dist/scrollreveal/index.d.ts"
|
|
158
|
+
],
|
|
159
|
+
"vivus": [
|
|
160
|
+
"./dist/vivus/index.d.ts"
|
|
154
161
|
]
|
|
155
162
|
}
|
|
156
163
|
},
|
|
@@ -390,6 +397,16 @@
|
|
|
390
397
|
"default": "./dist/scrollreveal/index.cjs"
|
|
391
398
|
}
|
|
392
399
|
},
|
|
400
|
+
"./vivus": {
|
|
401
|
+
"import": {
|
|
402
|
+
"types": "./dist/vivus/index.d.mts",
|
|
403
|
+
"default": "./dist/vivus/index.mjs"
|
|
404
|
+
},
|
|
405
|
+
"require": {
|
|
406
|
+
"types": "./dist/vivus/index.d.ts",
|
|
407
|
+
"default": "./dist/vivus/index.cjs"
|
|
408
|
+
}
|
|
409
|
+
},
|
|
393
410
|
"./package.json": "./package.json"
|
|
394
411
|
},
|
|
395
412
|
"scripts": {
|
|
@@ -417,6 +434,7 @@
|
|
|
417
434
|
"tsup": "^8.0.0",
|
|
418
435
|
"typescript": "^5.0.0",
|
|
419
436
|
"vitest": "^2.0.0",
|
|
437
|
+
"vivus": "^0.4.6",
|
|
420
438
|
"vue": "^3.5.34"
|
|
421
439
|
},
|
|
422
440
|
"sideEffects": [
|
|
@@ -424,7 +442,8 @@
|
|
|
424
442
|
"./dist/cdn/*",
|
|
425
443
|
"./src/web-component/*",
|
|
426
444
|
"./src/cdn.ts",
|
|
427
|
-
"./src/scrollreveal/cdn.ts"
|
|
445
|
+
"./src/scrollreveal/cdn.ts",
|
|
446
|
+
"./src/vivus/cdn.ts"
|
|
428
447
|
],
|
|
429
448
|
"engines": {
|
|
430
449
|
"node": ">=18"
|