svg-scroll-draw 2.23.1 → 2.23.4
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 +18 -19
- package/dist/angular/index.cjs +3 -3
- package/dist/angular/index.mjs +1 -1
- package/dist/astro/index.cjs +2 -2
- package/dist/astro/index.mjs +1 -1
- package/dist/cdn/svg-scroll-draw.dev.global.js +140 -176
- package/dist/cdn/svg-scroll-draw.global.js +3 -3
- package/dist/chunk-6TWFLRUB.mjs +3 -0
- package/dist/{chunk-OTDD2ROH.mjs → chunk-DSFD227B.mjs} +1 -1
- package/dist/chunk-I73SOXBN.mjs +1 -0
- package/dist/chunk-NLPSVYFP.mjs +1 -0
- package/dist/chunk-OPXWNJBG.mjs +1 -0
- package/dist/chunk-QFSTKVA3.mjs +1 -0
- package/dist/chunk-UPWWULKI.mjs +1 -0
- package/dist/chunk-XC5NR2MU.mjs +1 -0
- package/dist/{chunk-GVBO5GRD.mjs → chunk-XTPAW6XR.mjs} +1 -1
- package/dist/{chunk-VMUJMXKO.mjs → chunk-ZNCZYV3Q.mjs} +1 -1
- package/dist/group/index.cjs +2 -2
- package/dist/group/index.d.mts +4 -2
- package/dist/group/index.d.ts +4 -2
- package/dist/group/index.mjs +1 -1
- package/dist/horizontal/index.cjs +1 -1
- package/dist/horizontal/index.d.mts +10 -7
- package/dist/horizontal/index.d.ts +10 -7
- package/dist/horizontal/index.mjs +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +1 -1
- package/dist/nuxt/index.cjs +3 -3
- package/dist/nuxt/index.mjs +1 -1
- package/dist/progress/index.cjs +1 -1
- package/dist/progress/index.mjs +1 -1
- package/dist/react/index.cjs +3 -3
- package/dist/react/index.d.mts +3 -1
- package/dist/react/index.d.ts +3 -1
- package/dist/react/index.mjs +1 -1
- package/dist/reveal/index.cjs +1 -1
- package/dist/reveal/index.d.mts +9 -3
- package/dist/reveal/index.d.ts +9 -3
- package/dist/reveal/index.mjs +1 -1
- package/dist/snap/index.cjs +1 -1
- package/dist/snap/index.mjs +1 -1
- package/dist/solid/index.cjs +3 -3
- package/dist/solid/index.mjs +1 -1
- package/dist/svelte/index.cjs +3 -3
- package/dist/svelte/index.mjs +1 -1
- package/dist/text/index.cjs +1 -1
- package/dist/text/index.mjs +1 -1
- package/dist/timeline/index.cjs +1 -1
- package/dist/timeline/index.mjs +1 -1
- package/dist/video/index.cjs +1 -1
- package/dist/video/index.mjs +1 -1
- package/dist/vue/index.cjs +3 -3
- package/dist/vue/index.mjs +1 -1
- package/dist/web-component/index.cjs +3 -3
- package/dist/web-component/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-DY5JCXVR.mjs +0 -1
- package/dist/chunk-HX4SP5WN.mjs +0 -3
- package/dist/chunk-KV3WCPQ5.mjs +0 -1
- package/dist/chunk-LTCJVVSC.mjs +0 -1
- package/dist/chunk-WXUOF4NM.mjs +0 -1
- package/dist/chunk-YWKPTYSG.mjs +0 -1
- package/dist/chunk-YZV4Z3EQ.mjs +0 -1
|
@@ -150,7 +150,7 @@ var SvgScrollDraw = (() => {
|
|
|
150
150
|
const rect = el.getBoundingClientRect();
|
|
151
151
|
const size = axis === "x" ? rect.width : rect.height;
|
|
152
152
|
if (scrollEl) {
|
|
153
|
-
const top = axis === "x" ? rect.left - scrollEl.getBoundingClientRect().left + scrollEl.scrollLeft : rect.top - scrollEl.getBoundingClientRect().top + scrollEl.scrollTop;
|
|
153
|
+
const top = axis === "x" ? rect.left - scrollEl.getBoundingClientRect().left - scrollEl.clientLeft + scrollEl.scrollLeft : rect.top - scrollEl.getBoundingClientRect().top - scrollEl.clientTop + scrollEl.scrollTop;
|
|
154
154
|
return { top, height: size, scroll: 0 };
|
|
155
155
|
}
|
|
156
156
|
return {
|
|
@@ -162,6 +162,8 @@ var SvgScrollDraw = (() => {
|
|
|
162
162
|
|
|
163
163
|
// src/core/geometry.ts
|
|
164
164
|
function getElementLength(el) {
|
|
165
|
+
const declared = parseFloat(el.getAttribute("pathLength") ?? "");
|
|
166
|
+
if (declared > 0) return declared;
|
|
165
167
|
const tag = el.tagName.toLowerCase();
|
|
166
168
|
if (tag === "rect") {
|
|
167
169
|
const w = parseFloat(el.getAttribute("width") ?? "0");
|
|
@@ -536,8 +538,8 @@ var SvgScrollDraw = (() => {
|
|
|
536
538
|
} = options;
|
|
537
539
|
const clipDirection = clip === true ? "left" : typeof clip === "string" ? clip : false;
|
|
538
540
|
const easeFn = typeof easing === "function" ? easing : EASINGS[easing] ?? EASINGS.linear;
|
|
539
|
-
const startConfig = parseTrigger(trigger.start
|
|
540
|
-
const endConfig = parseTrigger(trigger.end
|
|
541
|
+
const startConfig = parseTrigger(trigger.start || "top bottom");
|
|
542
|
+
const endConfig = parseTrigger(trigger.end || "bottom top");
|
|
541
543
|
const scrollEl = typeof scrollContainer === "string" ? document.querySelector(scrollContainer) : scrollContainer ?? null;
|
|
542
544
|
const colorFrom = Array.isArray(strokeColor) ? strokeColor[0] : null;
|
|
543
545
|
const colorTo = Array.isArray(strokeColor) ? strokeColor[1] : typeof strokeColor === "string" ? strokeColor : null;
|
|
@@ -630,6 +632,9 @@ var SvgScrollDraw = (() => {
|
|
|
630
632
|
};
|
|
631
633
|
return inst;
|
|
632
634
|
}
|
|
635
|
+
function latch(i, raw) {
|
|
636
|
+
return once && !autoReverse ? Math.max(frozenAlpha, easeFn(frozenPath[i] = Math.max(frozenPath[i] ?? 0, raw))) : easeFn(raw);
|
|
637
|
+
}
|
|
633
638
|
function applyAlpha(alpha, dir) {
|
|
634
639
|
container.style.setProperty("--scroll-draw-progress", String(alpha));
|
|
635
640
|
if (clipDirection) {
|
|
@@ -637,28 +642,28 @@ var SvgScrollDraw = (() => {
|
|
|
637
642
|
container.style.clipPath = computeClipPath(a);
|
|
638
643
|
return;
|
|
639
644
|
}
|
|
640
|
-
paths.forEach((el, i) =>
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
645
|
+
paths.forEach((el, i) => paint(el, i, alpha, dir));
|
|
646
|
+
}
|
|
647
|
+
function paint(el, i, alpha, dir) {
|
|
648
|
+
el.style.strokeDashoffset = dir === "reverse" ? `${lengths[i] * alpha}` : `${lengths[i] * (1 - alpha)}`;
|
|
649
|
+
if (fade) el.style.opacity = dir === "reverse" ? `${1 - alpha}` : `${alpha}`;
|
|
650
|
+
if (colorFrom && colorTo) el.style.stroke = lerpColor(colorFrom, colorTo, alpha);
|
|
651
|
+
else if (colorTo) el.style.stroke = colorTo;
|
|
652
|
+
if (widthFrom !== null && widthTo !== null)
|
|
653
|
+
el.style.strokeWidth = `${widthFrom + (widthTo - widthFrom) * alpha}`;
|
|
654
|
+
else if (widthTo !== null)
|
|
655
|
+
el.style.strokeWidth = `${widthTo}`;
|
|
656
|
+
if (fillOpacityFrom !== null && fillOpacityTo !== null)
|
|
657
|
+
el.style.fillOpacity = `${fillOpacityFrom + (fillOpacityTo - fillOpacityFrom) * alpha}`;
|
|
658
|
+
else if (fillOpacityTo !== null)
|
|
659
|
+
el.style.fillOpacity = `${fillOpacityTo}`;
|
|
660
|
+
if (morphTo && el.tagName.toLowerCase() === "path" && originalDs[i])
|
|
661
|
+
el.setAttribute("d", morphPath(originalDs[i], morphTo, alpha));
|
|
657
662
|
}
|
|
658
663
|
function resetPaths() {
|
|
659
664
|
container.style.setProperty("--scroll-draw-progress", "0");
|
|
660
665
|
if (clipDirection) {
|
|
661
|
-
container.style.clipPath = computeClipPath(0);
|
|
666
|
+
container.style.clipPath = computeClipPath(direction === "reverse" ? 1 : 0);
|
|
662
667
|
return;
|
|
663
668
|
}
|
|
664
669
|
paths.forEach((el, i) => {
|
|
@@ -673,13 +678,26 @@ var SvgScrollDraw = (() => {
|
|
|
673
678
|
el.setAttribute("d", originalDs[i]);
|
|
674
679
|
});
|
|
675
680
|
}
|
|
676
|
-
|
|
681
|
+
function measure(el, i) {
|
|
682
|
+
const d = el.getAttribute("d");
|
|
683
|
+
let len = getElementLength(el);
|
|
684
|
+
if (morphTo && originalDs[i]) {
|
|
685
|
+
el.setAttribute("d", morphTo);
|
|
686
|
+
const target = getElementLength(el);
|
|
687
|
+
el.setAttribute("d", originalDs[i]);
|
|
688
|
+
len = Math.max(getElementLength(el), target);
|
|
689
|
+
el.setAttribute("d", d);
|
|
690
|
+
}
|
|
691
|
+
lengths[i] = len;
|
|
692
|
+
el.style.strokeDasharray = `${len}`;
|
|
693
|
+
}
|
|
694
|
+
paths.forEach((el, i) => {
|
|
677
695
|
checkElement(el);
|
|
678
|
-
const len = getElementLength(el);
|
|
679
|
-
lengths.push(len);
|
|
680
696
|
const isPath = el.tagName.toLowerCase() === "path";
|
|
681
697
|
if (isPath) originalDs.push(el.getAttribute("d") ?? "");
|
|
682
698
|
else originalDs.push("");
|
|
699
|
+
measure(el, i);
|
|
700
|
+
const len = lengths[i];
|
|
683
701
|
if (morphTo) {
|
|
684
702
|
if (!isPath) {
|
|
685
703
|
warn(`morphTo only applies to <path> elements \u2014 ignored on <${el.tagName}>.`, el);
|
|
@@ -688,7 +706,6 @@ var SvgScrollDraw = (() => {
|
|
|
688
706
|
}
|
|
689
707
|
}
|
|
690
708
|
if (prefersReduced) {
|
|
691
|
-
el.style.strokeDasharray = `${len}`;
|
|
692
709
|
el.style.strokeDashoffset = direction === "reverse" ? `${len}` : "0";
|
|
693
710
|
if (fade) el.style.opacity = "1";
|
|
694
711
|
if (colorTo) el.style.stroke = colorTo;
|
|
@@ -696,7 +713,6 @@ var SvgScrollDraw = (() => {
|
|
|
696
713
|
if (fillOpacityTo !== null) el.style.fillOpacity = `${fillOpacityTo}`;
|
|
697
714
|
if (morphTo && el.tagName.toLowerCase() === "path") el.setAttribute("d", morphTo);
|
|
698
715
|
} else {
|
|
699
|
-
el.style.strokeDasharray = `${len}`;
|
|
700
716
|
el.style.strokeDashoffset = direction === "reverse" ? "0" : `${len}`;
|
|
701
717
|
if (fade) el.style.opacity = direction === "reverse" ? "1" : "0";
|
|
702
718
|
else el.style.opacity = "";
|
|
@@ -705,19 +721,8 @@ var SvgScrollDraw = (() => {
|
|
|
705
721
|
if (fillOpacityFrom !== null) el.style.fillOpacity = `${fillOpacityFrom}`;
|
|
706
722
|
}
|
|
707
723
|
});
|
|
708
|
-
if (
|
|
709
|
-
if (
|
|
710
|
-
container.style.clipPath = computeClipPath(1);
|
|
711
|
-
onComplete?.();
|
|
712
|
-
return { destroy: () => {
|
|
713
|
-
}, replay: () => {
|
|
714
|
-
}, pause: () => {
|
|
715
|
-
}, resume: () => {
|
|
716
|
-
}, seek: () => {
|
|
717
|
-
}, getProgress: () => 1 };
|
|
718
|
-
}
|
|
719
|
-
container.style.clipPath = computeClipPath(0);
|
|
720
|
-
} else if (prefersReduced) {
|
|
724
|
+
if (prefersReduced) {
|
|
725
|
+
if (clipDirection) container.style.clipPath = computeClipPath(1);
|
|
721
726
|
onComplete?.();
|
|
722
727
|
return { destroy: () => {
|
|
723
728
|
}, replay: () => {
|
|
@@ -726,9 +731,12 @@ var SvgScrollDraw = (() => {
|
|
|
726
731
|
}, seek: () => {
|
|
727
732
|
}, getProgress: () => 1 };
|
|
728
733
|
}
|
|
734
|
+
if (clipDirection) container.style.clipPath = computeClipPath(direction === "reverse" ? 1 : 0);
|
|
729
735
|
const cssTiming = typeof easing === "string" ? cssTimingFor(easing) : null;
|
|
730
736
|
function nativeEligible() {
|
|
731
737
|
if (native === false) return false;
|
|
738
|
+
if (autoplay) return false;
|
|
739
|
+
if (debug && IS_DEV) return false;
|
|
732
740
|
if (!supportsNativeTimeline()) return false;
|
|
733
741
|
if (!paths.length) return false;
|
|
734
742
|
if (!cssTiming) return false;
|
|
@@ -746,8 +754,8 @@ var SvgScrollDraw = (() => {
|
|
|
746
754
|
if (delay > 0) return false;
|
|
747
755
|
if (onProgress || onStart || onComplete || onEnter || onLeave || onEnterBack || onLeaveBack) return false;
|
|
748
756
|
if (strokeColor != null || strokeWidth != null || fillOpacity != null) return false;
|
|
749
|
-
if ((trigger.start
|
|
750
|
-
if ((trigger.end
|
|
757
|
+
if ((trigger.start || "top bottom").trim() !== "top bottom") return false;
|
|
758
|
+
if ((trigger.end || "bottom top").trim() !== "bottom top") return false;
|
|
751
759
|
return true;
|
|
752
760
|
}
|
|
753
761
|
function buildNative() {
|
|
@@ -842,9 +850,8 @@ var SvgScrollDraw = (() => {
|
|
|
842
850
|
*/
|
|
843
851
|
refresh() {
|
|
844
852
|
paths.forEach((el, i) => {
|
|
845
|
-
|
|
853
|
+
measure(el, i);
|
|
846
854
|
el.style.setProperty("--ssd-len", String(lengths[i]));
|
|
847
|
-
el.style.strokeDasharray = `${lengths[i]}`;
|
|
848
855
|
});
|
|
849
856
|
}
|
|
850
857
|
};
|
|
@@ -852,11 +859,13 @@ var SvgScrollDraw = (() => {
|
|
|
852
859
|
if (nativeEligible()) return tracked(buildNative());
|
|
853
860
|
function buildAutoplay() {
|
|
854
861
|
const effectiveDuration = Math.max(1, duration);
|
|
862
|
+
const runMs = clipDirection ? effectiveDuration : effectiveDuration * (1 + Math.max(0, paths.length - 1) * stagger);
|
|
855
863
|
let startTime = 0;
|
|
856
864
|
let pausedElapsed = 0;
|
|
857
865
|
let running = false;
|
|
858
866
|
function applyAutoAlpha(elapsed) {
|
|
859
867
|
let allDone = true;
|
|
868
|
+
const runRaw = Math.min(1, Math.max(0, elapsed / runMs));
|
|
860
869
|
if (clipDirection) {
|
|
861
870
|
const raw = Math.min(1, Math.max(0, elapsed / effectiveDuration));
|
|
862
871
|
const alpha = easeFn(raw);
|
|
@@ -869,32 +878,16 @@ var SvgScrollDraw = (() => {
|
|
|
869
878
|
paths.forEach((el, i) => {
|
|
870
879
|
const staggerMs = i * stagger * effectiveDuration;
|
|
871
880
|
const raw = Math.min(1, Math.max(0, (elapsed - staggerMs) / effectiveDuration));
|
|
872
|
-
|
|
873
|
-
el.style.strokeDashoffset = direction === "reverse" ? `${lengths[i] * alpha}` : `${lengths[i] * (1 - alpha)}`;
|
|
874
|
-
if (fade) el.style.opacity = direction === "reverse" ? `${1 - alpha}` : `${alpha}`;
|
|
875
|
-
if (colorFrom && colorTo) el.style.stroke = lerpColor(colorFrom, colorTo, alpha);
|
|
876
|
-
else if (colorTo) el.style.stroke = colorTo;
|
|
877
|
-
if (widthFrom !== null && widthTo !== null)
|
|
878
|
-
el.style.strokeWidth = `${widthFrom + (widthTo - widthFrom) * alpha}`;
|
|
879
|
-
else if (widthTo !== null)
|
|
880
|
-
el.style.strokeWidth = `${widthTo}`;
|
|
881
|
-
if (fillOpacityFrom !== null && fillOpacityTo !== null)
|
|
882
|
-
el.style.fillOpacity = `${fillOpacityFrom + (fillOpacityTo - fillOpacityFrom) * alpha}`;
|
|
883
|
-
else if (fillOpacityTo !== null)
|
|
884
|
-
el.style.fillOpacity = `${fillOpacityTo}`;
|
|
885
|
-
if (morphTo && el.tagName.toLowerCase() === "path" && originalDs[i])
|
|
886
|
-
el.setAttribute("d", morphPath(originalDs[i], morphTo, alpha));
|
|
887
|
-
if (i === 0) {
|
|
888
|
-
currentAlpha = alpha;
|
|
889
|
-
onProgress?.(alpha);
|
|
890
|
-
container.style.setProperty("--scroll-draw-progress", String(alpha));
|
|
891
|
-
}
|
|
881
|
+
paint(el, i, easeFn(raw), direction);
|
|
892
882
|
if (raw < 1) allDone = false;
|
|
893
883
|
});
|
|
884
|
+
const runAlpha = easeFn(runRaw);
|
|
885
|
+
currentAlpha = runAlpha;
|
|
886
|
+
onProgress?.(runAlpha);
|
|
887
|
+
container.style.setProperty("--scroll-draw-progress", String(runAlpha));
|
|
894
888
|
}
|
|
895
889
|
if (waypoints) {
|
|
896
|
-
const
|
|
897
|
-
const globalAlpha = easeFn(globalRaw);
|
|
890
|
+
const globalAlpha = easeFn(runRaw);
|
|
898
891
|
for (const key in waypoints) {
|
|
899
892
|
const t = parseFloat(key);
|
|
900
893
|
if (globalAlpha >= t && !firedWaypoints.has(t)) {
|
|
@@ -915,7 +908,7 @@ var SvgScrollDraw = (() => {
|
|
|
915
908
|
const done = applyAutoAlpha(elapsed);
|
|
916
909
|
if (done && !completed) {
|
|
917
910
|
completed = true;
|
|
918
|
-
applyAutoAlpha(
|
|
911
|
+
applyAutoAlpha(runMs);
|
|
919
912
|
onComplete?.();
|
|
920
913
|
const maxRepeats = repeat === "infinite" ? Infinity : repeat ?? 0;
|
|
921
914
|
if (repeatCount < maxRepeats) {
|
|
@@ -965,12 +958,7 @@ var SvgScrollDraw = (() => {
|
|
|
965
958
|
let resizeTimer2;
|
|
966
959
|
function onResize2() {
|
|
967
960
|
clearTimeout(resizeTimer2);
|
|
968
|
-
resizeTimer2 = setTimeout(() =>
|
|
969
|
-
paths.forEach((el, i) => {
|
|
970
|
-
lengths[i] = getElementLength(el);
|
|
971
|
-
el.style.strokeDasharray = `${lengths[i]}`;
|
|
972
|
-
});
|
|
973
|
-
}, 150);
|
|
961
|
+
resizeTimer2 = setTimeout(() => paths.forEach(measure), 150);
|
|
974
962
|
}
|
|
975
963
|
window.addEventListener("resize", onResize2);
|
|
976
964
|
window.addEventListener("orientationchange", onResize2);
|
|
@@ -1006,7 +994,7 @@ var SvgScrollDraw = (() => {
|
|
|
1006
994
|
const clamped = Math.min(1, Math.max(0, p));
|
|
1007
995
|
currentAlpha = clamped;
|
|
1008
996
|
paused = true;
|
|
1009
|
-
pausedElapsed = clamped *
|
|
997
|
+
pausedElapsed = clamped * runMs;
|
|
1010
998
|
startTime = performance.now() - pausedElapsed;
|
|
1011
999
|
cancelAnimationFrame(rafId);
|
|
1012
1000
|
applyAutoAlpha(pausedElapsed);
|
|
@@ -1017,10 +1005,7 @@ var SvgScrollDraw = (() => {
|
|
|
1017
1005
|
/** No trigger window on this path — it runs on time — so lengths only. */
|
|
1018
1006
|
refresh() {
|
|
1019
1007
|
clearTimeout(resizeTimer2);
|
|
1020
|
-
paths.forEach(
|
|
1021
|
-
lengths[i] = getElementLength(el);
|
|
1022
|
-
el.style.strokeDasharray = `${lengths[i]}`;
|
|
1023
|
-
});
|
|
1008
|
+
paths.forEach(measure);
|
|
1024
1009
|
}
|
|
1025
1010
|
};
|
|
1026
1011
|
}
|
|
@@ -1058,11 +1043,7 @@ var SvgScrollDraw = (() => {
|
|
|
1058
1043
|
}
|
|
1059
1044
|
prevRawProgress = rawProgress;
|
|
1060
1045
|
if (clipDirection) {
|
|
1061
|
-
|
|
1062
|
-
if (once && !autoReverse) {
|
|
1063
|
-
frozenAlpha = Math.max(frozenAlpha, alpha);
|
|
1064
|
-
alpha = frozenAlpha;
|
|
1065
|
-
}
|
|
1046
|
+
const alpha = latch(0, computeProgress(currentScroll, tStart, tEnd, effectiveSpeed));
|
|
1066
1047
|
currentAlpha = alpha;
|
|
1067
1048
|
container.style.setProperty("--scroll-draw-progress", String(alpha));
|
|
1068
1049
|
const visual = effectiveDir === "reverse" ? 1 - alpha : alpha;
|
|
@@ -1080,9 +1061,10 @@ var SvgScrollDraw = (() => {
|
|
|
1080
1061
|
repeatCount++;
|
|
1081
1062
|
repeatTimer = setTimeout(() => {
|
|
1082
1063
|
frozenAlpha = -1;
|
|
1064
|
+
frozenPath = [];
|
|
1083
1065
|
started = false;
|
|
1084
1066
|
completed = false;
|
|
1085
|
-
|
|
1067
|
+
resetPaths();
|
|
1086
1068
|
}, repeatDelay);
|
|
1087
1069
|
}
|
|
1088
1070
|
} else if (alpha < 1 && !once) {
|
|
@@ -1093,24 +1075,8 @@ var SvgScrollDraw = (() => {
|
|
|
1093
1075
|
}
|
|
1094
1076
|
paths.forEach((el, i) => {
|
|
1095
1077
|
const offset = i * staggerFit * range;
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
alpha = frozenPath[i] = Math.max(frozenPath[i] ?? frozenAlpha, alpha);
|
|
1099
|
-
}
|
|
1100
|
-
el.style.strokeDashoffset = effectiveDir === "reverse" ? `${lengths[i] * alpha}` : `${lengths[i] * (1 - alpha)}`;
|
|
1101
|
-
if (fade) el.style.opacity = effectiveDir === "reverse" ? `${1 - alpha}` : `${alpha}`;
|
|
1102
|
-
if (colorFrom && colorTo) el.style.stroke = lerpColor(colorFrom, colorTo, alpha);
|
|
1103
|
-
else if (colorTo) el.style.stroke = colorTo;
|
|
1104
|
-
if (widthFrom !== null && widthTo !== null)
|
|
1105
|
-
el.style.strokeWidth = `${widthFrom + (widthTo - widthFrom) * alpha}`;
|
|
1106
|
-
else if (widthTo !== null)
|
|
1107
|
-
el.style.strokeWidth = `${widthTo}`;
|
|
1108
|
-
if (fillOpacityFrom !== null && fillOpacityTo !== null)
|
|
1109
|
-
el.style.fillOpacity = `${fillOpacityFrom + (fillOpacityTo - fillOpacityFrom) * alpha}`;
|
|
1110
|
-
else if (fillOpacityTo !== null)
|
|
1111
|
-
el.style.fillOpacity = `${fillOpacityTo}`;
|
|
1112
|
-
if (morphTo && el.tagName.toLowerCase() === "path" && originalDs[i])
|
|
1113
|
-
el.setAttribute("d", morphPath(originalDs[i], morphTo, alpha));
|
|
1078
|
+
const alpha = latch(i, computeProgress(currentScroll, tStart + offset, tEnd + offset, effectiveSpeed));
|
|
1079
|
+
paint(el, i, alpha, effectiveDir);
|
|
1114
1080
|
if (i === 0) {
|
|
1115
1081
|
currentAlpha = alpha;
|
|
1116
1082
|
onProgress?.(alpha);
|
|
@@ -1190,10 +1156,7 @@ var SvgScrollDraw = (() => {
|
|
|
1190
1156
|
{ root: scrollEl ?? null, threshold, rootMargin }
|
|
1191
1157
|
);
|
|
1192
1158
|
function remeasure() {
|
|
1193
|
-
paths.forEach(
|
|
1194
|
-
lengths[i] = getElementLength(el);
|
|
1195
|
-
el.style.strokeDasharray = `${lengths[i]}`;
|
|
1196
|
-
});
|
|
1159
|
+
paths.forEach(measure);
|
|
1197
1160
|
cacheTriggers();
|
|
1198
1161
|
dirty = true;
|
|
1199
1162
|
}
|
|
@@ -1398,8 +1361,8 @@ var SvgScrollDraw = (() => {
|
|
|
1398
1361
|
onLeaveBack
|
|
1399
1362
|
} = options;
|
|
1400
1363
|
const easeFn = typeof easing === "function" ? easing : EASINGS[easing] ?? EASINGS["ease-out"];
|
|
1401
|
-
const startConfig = parseTrigger(trigger.start
|
|
1402
|
-
const endConfig = parseTrigger(trigger.end
|
|
1364
|
+
const startConfig = parseTrigger(trigger.start || "top bottom");
|
|
1365
|
+
const endConfig = parseTrigger(trigger.end || "bottom top");
|
|
1403
1366
|
const triggerEl = triggerElement ?? el;
|
|
1404
1367
|
const scrollEl = typeof scrollContainer === "string" ? document.querySelector(scrollContainer) : scrollContainer ?? null;
|
|
1405
1368
|
const entries = Object.entries(props).map(([key, val]) => ({
|
|
@@ -1436,6 +1399,14 @@ var SvgScrollDraw = (() => {
|
|
|
1436
1399
|
return { ...NOOP, destroy: restoreInline, getProgress: () => 1 };
|
|
1437
1400
|
}
|
|
1438
1401
|
resolveFromValues();
|
|
1402
|
+
const scrollPos = () => {
|
|
1403
|
+
if (scrollEl) return axis === "x" ? scrollEl.scrollLeft : scrollEl.scrollTop;
|
|
1404
|
+
return axis === "x" ? window.scrollX : window.scrollY;
|
|
1405
|
+
};
|
|
1406
|
+
const vpSize = () => {
|
|
1407
|
+
if (scrollEl) return axis === "x" ? scrollEl.clientWidth : scrollEl.clientHeight;
|
|
1408
|
+
return axis === "x" ? window.innerWidth : window.innerHeight;
|
|
1409
|
+
};
|
|
1439
1410
|
const cssTiming = typeof easing === "string" ? cssTimingFor(easing) : null;
|
|
1440
1411
|
function nativeEligible() {
|
|
1441
1412
|
if (!native) return false;
|
|
@@ -1448,8 +1419,8 @@ var SvgScrollDraw = (() => {
|
|
|
1448
1419
|
if (speed !== 1) return false;
|
|
1449
1420
|
if (onProgress || onComplete || onEnter || onLeave || onEnterBack || onLeaveBack) return false;
|
|
1450
1421
|
if (velocityScale !== false) return false;
|
|
1451
|
-
if ((trigger.start
|
|
1452
|
-
if ((trigger.end
|
|
1422
|
+
if ((trigger.start || "top bottom").trim() !== "top bottom") return false;
|
|
1423
|
+
if ((trigger.end || "bottom top").trim() !== "bottom top") return false;
|
|
1453
1424
|
for (const entry of entries) {
|
|
1454
1425
|
if (!NATIVE_SAFE_PROPS.has(entry.prop)) return false;
|
|
1455
1426
|
}
|
|
@@ -1464,11 +1435,9 @@ var SvgScrollDraw = (() => {
|
|
|
1464
1435
|
style.textContent = `@keyframes ${cls}{from{${fromBody}}to{${toBody}}}.${cls}{animation-name:${cls};animation-duration:auto;animation-timing-function:${cssTiming};animation-fill-mode:both;animation-timeline:view();animation-range:cover 0% cover 100%;}`;
|
|
1465
1436
|
document.head.appendChild(style);
|
|
1466
1437
|
el.classList.add(cls);
|
|
1467
|
-
const scrollPos2 = () => axis === "x" ? window.scrollX : window.scrollY;
|
|
1468
|
-
const vpSize2 = () => axis === "x" ? window.innerWidth : window.innerHeight;
|
|
1469
1438
|
const liveTriggers = () => {
|
|
1470
1439
|
const rect = el.getBoundingClientRect();
|
|
1471
|
-
return computeTriggers({ top: rect.top, height: rect.height },
|
|
1440
|
+
return computeTriggers({ top: rect.top, height: rect.height }, scrollPos(), vpSize(), startConfig, endConfig);
|
|
1472
1441
|
};
|
|
1473
1442
|
_register(el, {
|
|
1474
1443
|
type: "animate",
|
|
@@ -1506,7 +1475,7 @@ var SvgScrollDraw = (() => {
|
|
|
1506
1475
|
},
|
|
1507
1476
|
getProgress() {
|
|
1508
1477
|
const { tStart: tStart2, tEnd: tEnd2 } = liveTriggers();
|
|
1509
|
-
return easeFn(computeProgress(
|
|
1478
|
+
return easeFn(computeProgress(scrollPos(), tStart2, tEnd2, speed));
|
|
1510
1479
|
}
|
|
1511
1480
|
};
|
|
1512
1481
|
return instance;
|
|
@@ -1515,22 +1484,15 @@ var SvgScrollDraw = (() => {
|
|
|
1515
1484
|
let tStart = 0;
|
|
1516
1485
|
let tEnd = 0;
|
|
1517
1486
|
let rafId = 0;
|
|
1518
|
-
let
|
|
1487
|
+
let painted = NaN;
|
|
1519
1488
|
let paused = false;
|
|
1520
1489
|
let frozenAlpha = -1;
|
|
1490
|
+
let frozenRaw = 0;
|
|
1521
1491
|
let currentAlpha = 0;
|
|
1522
1492
|
let completed = false;
|
|
1523
1493
|
let prevRawProgress = NaN;
|
|
1524
1494
|
let prevVelScroll = -1;
|
|
1525
1495
|
let prevVelTime = 0;
|
|
1526
|
-
const scrollPos = () => {
|
|
1527
|
-
if (scrollEl) return axis === "x" ? scrollEl.scrollLeft : scrollEl.scrollTop;
|
|
1528
|
-
return axis === "x" ? window.scrollX : window.scrollY;
|
|
1529
|
-
};
|
|
1530
|
-
const vpSize = () => {
|
|
1531
|
-
if (scrollEl) return axis === "x" ? scrollEl.clientWidth : scrollEl.clientHeight;
|
|
1532
|
-
return axis === "x" ? window.innerWidth : window.innerHeight;
|
|
1533
|
-
};
|
|
1534
1496
|
const moving = triggerEl === el ? entries : [];
|
|
1535
1497
|
let measured = false;
|
|
1536
1498
|
function cacheTriggers() {
|
|
@@ -1569,8 +1531,12 @@ var SvgScrollDraw = (() => {
|
|
|
1569
1531
|
else if (prevRawProgress >= 1 && raw < 1) onEnterBack?.();
|
|
1570
1532
|
prevRawProgress = raw;
|
|
1571
1533
|
}
|
|
1534
|
+
const gate = (scroll) => computeProgress(scroll, tStart, tEnd, Math.min(speed, 1));
|
|
1535
|
+
function wake() {
|
|
1536
|
+
if (!rafId && !paused && gate(scrollPos()) !== painted) rafId = requestAnimationFrame(update);
|
|
1537
|
+
}
|
|
1572
1538
|
function update() {
|
|
1573
|
-
if (
|
|
1539
|
+
if (paused) return;
|
|
1574
1540
|
const now = performance.now();
|
|
1575
1541
|
const currentScroll = scrollPos();
|
|
1576
1542
|
let effectiveSpeed = speed;
|
|
@@ -1584,11 +1550,8 @@ var SvgScrollDraw = (() => {
|
|
|
1584
1550
|
prevVelTime = now;
|
|
1585
1551
|
const raw = tEnd === tStart ? 0 : (currentScroll - tStart) / (tEnd - tStart);
|
|
1586
1552
|
fireScrollCallbacks(raw);
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
frozenAlpha = Math.max(frozenAlpha, alpha);
|
|
1590
|
-
alpha = frozenAlpha;
|
|
1591
|
-
}
|
|
1553
|
+
const progress = computeProgress(currentScroll, tStart, tEnd, effectiveSpeed);
|
|
1554
|
+
const alpha = once ? Math.max(frozenAlpha, easeFn(frozenRaw = Math.max(frozenRaw, progress))) : easeFn(progress);
|
|
1592
1555
|
currentAlpha = alpha;
|
|
1593
1556
|
applyAlpha(alpha);
|
|
1594
1557
|
if (alpha >= 1 && !completed) {
|
|
@@ -1597,49 +1560,49 @@ var SvgScrollDraw = (() => {
|
|
|
1597
1560
|
} else if (alpha < 1 && !once) {
|
|
1598
1561
|
completed = false;
|
|
1599
1562
|
}
|
|
1600
|
-
|
|
1563
|
+
if (paused) return;
|
|
1564
|
+
painted = gate(currentScroll);
|
|
1565
|
+
rafId = painted > 0 && painted < 1 ? requestAnimationFrame(update) : 0;
|
|
1601
1566
|
}
|
|
1602
1567
|
cacheTriggers();
|
|
1603
1568
|
if (tEnd === tStart) {
|
|
1604
|
-
warn(
|
|
1605
|
-
"scrollAnimate: the trigger window has zero length (start and end resolve to the same scroll position), so this element will never animate. If the target is inside a position:sticky stage, measure the trigger from the container that holds the scroll room via `triggerElement`.",
|
|
1606
|
-
el
|
|
1607
|
-
);
|
|
1569
|
+
warn("scrollAnimate: zero-length trigger window, so it never animates. In a sticky stage, set triggerElement.", el);
|
|
1608
1570
|
}
|
|
1609
1571
|
{
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
currentAlpha
|
|
1613
|
-
|
|
1572
|
+
frozenRaw = computeProgress(scrollPos(), tStart, tEnd, speed);
|
|
1573
|
+
currentAlpha = easeFn(frozenRaw);
|
|
1574
|
+
applyAlpha(currentAlpha);
|
|
1575
|
+
}
|
|
1576
|
+
function remeasure() {
|
|
1577
|
+
cacheTriggers();
|
|
1578
|
+
wake();
|
|
1614
1579
|
}
|
|
1615
|
-
const observer2 = new IntersectionObserver(
|
|
1616
|
-
(ioEntries) => {
|
|
1617
|
-
ioEntries.forEach((e) => {
|
|
1618
|
-
isVisible = e.isIntersecting;
|
|
1619
|
-
if (isVisible && !paused) rafId = requestAnimationFrame(update);
|
|
1620
|
-
else cancelAnimationFrame(rafId);
|
|
1621
|
-
});
|
|
1622
|
-
},
|
|
1623
|
-
{ root: scrollEl ?? null }
|
|
1624
|
-
);
|
|
1625
1580
|
let resizeTimer;
|
|
1626
1581
|
function onResize() {
|
|
1627
1582
|
clearTimeout(resizeTimer);
|
|
1628
|
-
resizeTimer = setTimeout(
|
|
1583
|
+
resizeTimer = setTimeout(remeasure, 150);
|
|
1629
1584
|
}
|
|
1585
|
+
const scroller = scrollEl ?? window;
|
|
1586
|
+
scroller.addEventListener("scroll", wake, { passive: true });
|
|
1630
1587
|
window.addEventListener("resize", onResize);
|
|
1631
1588
|
window.addEventListener("orientationchange", onResize);
|
|
1632
1589
|
const unwatch = watchLayout([triggerEl], onResize);
|
|
1633
|
-
|
|
1590
|
+
wake();
|
|
1634
1591
|
_register(el, {
|
|
1635
1592
|
type: "animate",
|
|
1636
1593
|
getProgress: () => currentAlpha,
|
|
1637
1594
|
getTrigger: () => ({ tStart, tEnd })
|
|
1638
1595
|
});
|
|
1596
|
+
function halt() {
|
|
1597
|
+
paused = true;
|
|
1598
|
+
cancelAnimationFrame(rafId);
|
|
1599
|
+
rafId = 0;
|
|
1600
|
+
painted = NaN;
|
|
1601
|
+
}
|
|
1639
1602
|
return {
|
|
1640
1603
|
destroy() {
|
|
1641
|
-
|
|
1642
|
-
|
|
1604
|
+
halt();
|
|
1605
|
+
scroller.removeEventListener("scroll", wake);
|
|
1643
1606
|
window.removeEventListener("resize", onResize);
|
|
1644
1607
|
window.removeEventListener("orientationchange", onResize);
|
|
1645
1608
|
unwatch();
|
|
@@ -1649,34 +1612,32 @@ var SvgScrollDraw = (() => {
|
|
|
1649
1612
|
},
|
|
1650
1613
|
replay() {
|
|
1651
1614
|
frozenAlpha = -1;
|
|
1615
|
+
frozenRaw = 0;
|
|
1652
1616
|
completed = false;
|
|
1653
1617
|
currentAlpha = 0;
|
|
1654
1618
|
paused = false;
|
|
1655
1619
|
applyAlpha(0);
|
|
1620
|
+
painted = 0;
|
|
1621
|
+
wake();
|
|
1656
1622
|
},
|
|
1657
|
-
pause
|
|
1658
|
-
paused = true;
|
|
1659
|
-
cancelAnimationFrame(rafId);
|
|
1660
|
-
},
|
|
1623
|
+
pause: halt,
|
|
1661
1624
|
resume() {
|
|
1662
1625
|
if (!paused) return;
|
|
1663
1626
|
paused = false;
|
|
1664
|
-
|
|
1627
|
+
wake();
|
|
1665
1628
|
},
|
|
1666
1629
|
seek(p) {
|
|
1667
1630
|
const clamped = Math.min(1, Math.max(0, p));
|
|
1668
1631
|
currentAlpha = clamped;
|
|
1669
1632
|
frozenAlpha = clamped;
|
|
1670
|
-
|
|
1671
|
-
|
|
1633
|
+
frozenRaw = 0;
|
|
1634
|
+
halt();
|
|
1672
1635
|
applyAlpha(clamped);
|
|
1673
1636
|
},
|
|
1674
1637
|
getProgress() {
|
|
1675
1638
|
return currentAlpha;
|
|
1676
1639
|
},
|
|
1677
|
-
refresh
|
|
1678
|
-
cacheTriggers();
|
|
1679
|
-
}
|
|
1640
|
+
refresh: remeasure
|
|
1680
1641
|
};
|
|
1681
1642
|
}
|
|
1682
1643
|
|
|
@@ -1766,8 +1727,8 @@ var SvgScrollDraw = (() => {
|
|
|
1766
1727
|
} = options;
|
|
1767
1728
|
const fmt = decimals !== void 0 ? (n) => n.toFixed(decimals) : format ?? ((n) => String(Math.round(n)));
|
|
1768
1729
|
const easeFn = typeof easing === "function" ? easing : EASINGS[easing] ?? EASINGS["ease-out"];
|
|
1769
|
-
const startConfig = parseTrigger(trigger.start
|
|
1770
|
-
const endConfig = parseTrigger(trigger.end
|
|
1730
|
+
const startConfig = parseTrigger(trigger.start || "top 80%");
|
|
1731
|
+
const endConfig = parseTrigger(trigger.end || "top 20%");
|
|
1771
1732
|
if (prefersReduced) {
|
|
1772
1733
|
el.textContent = fmt(to);
|
|
1773
1734
|
onComplete?.();
|
|
@@ -1780,6 +1741,7 @@ var SvgScrollDraw = (() => {
|
|
|
1780
1741
|
let isVisible = false;
|
|
1781
1742
|
let paused = false;
|
|
1782
1743
|
let frozenAlpha = -1;
|
|
1744
|
+
let frozenRaw = 0;
|
|
1783
1745
|
let currentAlpha = 0;
|
|
1784
1746
|
let completed = false;
|
|
1785
1747
|
const scrollPos = () => window.scrollY;
|
|
@@ -1798,17 +1760,15 @@ var SvgScrollDraw = (() => {
|
|
|
1798
1760
|
tStart = result.tStart;
|
|
1799
1761
|
tEnd = result.tEnd;
|
|
1800
1762
|
}
|
|
1763
|
+
const savedVar = el.style.getPropertyValue("--scroll-draw-progress");
|
|
1801
1764
|
function applyAlpha(alpha) {
|
|
1802
1765
|
el.textContent = fmt(from + (to - from) * alpha);
|
|
1803
1766
|
el.style.setProperty("--scroll-draw-progress", String(alpha));
|
|
1804
1767
|
}
|
|
1805
1768
|
function update() {
|
|
1806
1769
|
if (!isVisible || paused) return;
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
frozenAlpha = Math.max(frozenAlpha, alpha);
|
|
1810
|
-
alpha = frozenAlpha;
|
|
1811
|
-
}
|
|
1770
|
+
const progress = computeProgress(scrollPos(), tStart, tEnd, 1);
|
|
1771
|
+
const alpha = once ? Math.max(frozenAlpha, easeFn(frozenRaw = Math.max(frozenRaw, progress))) : easeFn(progress);
|
|
1812
1772
|
currentAlpha = alpha;
|
|
1813
1773
|
applyAlpha(alpha);
|
|
1814
1774
|
if (alpha >= 1 && !completed) {
|
|
@@ -1821,8 +1781,8 @@ var SvgScrollDraw = (() => {
|
|
|
1821
1781
|
}
|
|
1822
1782
|
cacheTriggers();
|
|
1823
1783
|
{
|
|
1824
|
-
|
|
1825
|
-
|
|
1784
|
+
frozenRaw = computeProgress(scrollPos(), tStart, tEnd, 1);
|
|
1785
|
+
const initAlpha = easeFn(frozenRaw);
|
|
1826
1786
|
currentAlpha = initAlpha;
|
|
1827
1787
|
applyAlpha(initAlpha);
|
|
1828
1788
|
}
|
|
@@ -1849,6 +1809,11 @@ var SvgScrollDraw = (() => {
|
|
|
1849
1809
|
getProgress: () => currentAlpha,
|
|
1850
1810
|
getTrigger: () => ({ tStart, tEnd })
|
|
1851
1811
|
});
|
|
1812
|
+
function resume() {
|
|
1813
|
+
if (!paused) return;
|
|
1814
|
+
paused = false;
|
|
1815
|
+
if (isVisible) rafId = requestAnimationFrame(update);
|
|
1816
|
+
}
|
|
1852
1817
|
return {
|
|
1853
1818
|
destroy() {
|
|
1854
1819
|
cancelAnimationFrame(rafId);
|
|
@@ -1857,28 +1822,27 @@ var SvgScrollDraw = (() => {
|
|
|
1857
1822
|
window.removeEventListener("orientationchange", onResize);
|
|
1858
1823
|
unwatch();
|
|
1859
1824
|
clearTimeout(resizeTimer);
|
|
1825
|
+
el.style.setProperty("--scroll-draw-progress", savedVar);
|
|
1860
1826
|
_unregister(el);
|
|
1861
1827
|
},
|
|
1862
1828
|
replay() {
|
|
1863
1829
|
frozenAlpha = -1;
|
|
1830
|
+
frozenRaw = 0;
|
|
1864
1831
|
completed = false;
|
|
1865
1832
|
currentAlpha = 0;
|
|
1866
|
-
paused = false;
|
|
1867
1833
|
applyAlpha(0);
|
|
1834
|
+
resume();
|
|
1868
1835
|
},
|
|
1869
1836
|
pause() {
|
|
1870
1837
|
paused = true;
|
|
1871
1838
|
cancelAnimationFrame(rafId);
|
|
1872
1839
|
},
|
|
1873
|
-
resume
|
|
1874
|
-
if (!paused) return;
|
|
1875
|
-
paused = false;
|
|
1876
|
-
if (isVisible) rafId = requestAnimationFrame(update);
|
|
1877
|
-
},
|
|
1840
|
+
resume,
|
|
1878
1841
|
seek(p) {
|
|
1879
1842
|
const clamped = Math.min(1, Math.max(0, p));
|
|
1880
1843
|
currentAlpha = clamped;
|
|
1881
1844
|
frozenAlpha = clamped;
|
|
1845
|
+
frozenRaw = 0;
|
|
1882
1846
|
paused = true;
|
|
1883
1847
|
cancelAnimationFrame(rafId);
|
|
1884
1848
|
applyAlpha(clamped);
|