@laubloch/scrolly-motion
Version:
Advanced scroll animation library with breakpoint support, timeline presets.
1,540 lines • 62.2 kB
JavaScript
var N = Object.defineProperty;
var I = (u, e, t) => e in u ? N(u, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[e] = t;
var d = (u, e, t) => (I(u, typeof e != "symbol" ? e + "" : e, t), t);
const j = {
selector: "[data-scroll], [data-animation]",
defaultEnter: "50vh",
breakpoints: {
default: "(min-width: 1px)",
mobile: "(max-width: 767px)",
tablet: "(min-width: 768px) and (max-width: 1023px)",
desktop: "(min-width: 1024px)"
},
presets: {}
}, C = {
enterClassNames: [],
leaveClassNames: []
}, W = {
enter: "10vh",
exit: "40vh",
once: !1,
damping: 0,
friction: 0.95
}, A = [
"large",
"desktop",
"tablet",
"mobile",
"default"
];
function $(u, e) {
let t;
return function(...s) {
clearTimeout(t), t = setTimeout(() => u.apply(this, s), e);
};
}
function E(u, e) {
return u ? u.trim().replace(/^['"]|['"]$/g, "").split(/\s+/).filter(Boolean) : e;
}
function M(u, e) {
if (typeof u == "number")
return u > 0 && u < 1 ? u * e : u;
if (typeof u == "string") {
const t = u.match(/^(-?[\d.]+)(vh|px|%)$/);
if (t) {
const s = parseFloat(t[1]), r = t[2];
if (r === "%" || r === "vh")
return e * (s / 100);
if (r === "px")
return s;
}
}
return 0;
}
function L(u) {
const e = /* @__PURE__ */ new Map();
return Object.entries(u).forEach(([t, s]) => {
const r = window.matchMedia(s);
e.set(t, r);
}), e;
}
function Y(u) {
const e = [], t = [], s = { ...u };
if (u.selector && typeof u.selector != "string" && e.push("`selector` must be a string."), u.defaultEnter && typeof u.defaultEnter != "string" && e.push("`defaultEnter` must be a string."), u.breakpoints)
if (typeof u.breakpoints != "object" || u.breakpoints === null)
e.push("`breakpoints` must be an object.");
else
for (const r in u.breakpoints)
typeof u.breakpoints[r] != "string" && t.push(
`Breakpoint \`${r}\` has an invalid value. It must be a string.`
);
if (u.presets)
if (typeof u.presets != "object" || u.presets === null)
e.push("`presets` must be an object.");
else
for (const r in u.presets)
Array.isArray(u.presets[r]) || t.push(
`Preset \`${r}\` has an invalid value. It must be an array of TimelineStep objects.`
);
return {
isValid: e.length === 0,
errors: e,
warnings: t,
sanitizedConfig: s
};
}
class P {
constructor(e) {
d(this, "valueParser");
this.valueParser = e;
}
parse(e) {
try {
const t = [];
return e.split(";").forEach((r) => {
const n = r.trim(), o = n.indexOf(":");
if (o === -1)
return;
const a = n.substring(0, o), i = n.substring(o + 1);
let l;
if (a === "from")
l = 0;
else if (a === "to")
l = 1;
else if (a.startsWith("via-") && a.endsWith("%")) {
const h = a.substring(4, a.length - 1), p = parseFloat(h);
if (isNaN(p))
return;
l = p / 100;
} else if (l = parseFloat(a), isNaN(l))
return;
const c = {};
i.split("|").forEach((h) => {
if (h.startsWith("letter-spacing")) {
const f = h.substring(15);
c["letter-spacing"] = this.valueParser.parse(
"letter-spacing",
f
);
return;
}
const p = h.indexOf("-");
if (p > 0) {
const f = h.substring(0, p);
let g = h.substring(p + 1);
g.startsWith("-") && (g = g), f && g !== void 0 && (c[f] = this.valueParser.parse(f, g));
}
}), t.push({ at: l, properties: c });
}), t.sort((r, n) => r.at - n.at);
} catch (t) {
return console.error(
`ScrollyMotion: Failed to parse timeline: "${e}"`,
t
), [];
}
}
}
class V {
constructor(e) {
d(this, "pluginManager");
this.pluginManager = e;
}
parse(e, t) {
try {
const s = this.pluginManager.parse(e, t);
return s !== void 0 ? s : t.startsWith("[") && t.endsWith("]") ? this.parseArbitraryValue(e, t.slice(1, -1)) : this.parseTailwindValue(e, t);
} catch (s) {
return console.error(
`ScrollyMotion: Failed to parse value for property "${e}": "${t}"`,
s
), t;
}
}
parseArbitraryValue(e, t) {
if (e.includes("translate") || e.includes("scale") || e.includes("rotate") || e.includes("blur") || e.includes("grayscale") || e.includes("skew") || e.includes("perspective")) {
if (/^-?[\d.]+[a-z%]+$/i.test(t))
return t;
if (/^-?[\d.]+$/.test(t)) {
const s = parseFloat(t);
return e.includes("rotate") ? `${s}deg` : e.includes("scale") ? s : `${s}px`;
}
}
return e === "opacity" ? parseFloat(t) : t;
}
parseTailwindValue(e, t) {
if (e.includes("translate"))
return this.parseTailwindSpacing(t);
if (e === "opacity")
return this.parseTailwindOpacity(t);
if (e.includes("scale"))
return this.parseTailwindScale(t);
if (e.includes("rotate"))
return this.parseTailwindRotate(t);
if (e.includes("blur"))
return this.parseTailwindBlur(t);
if (e.includes("grayscale"))
return this.parseTailwindGrayscale(t);
if (e.includes("skew"))
return this.parseTailwindSkew(t);
if (e.includes("perspective"))
return this.parseTailwindPerspective(t);
const s = parseFloat(t);
return isNaN(s) ? t : s;
}
parseTailwindSpacing(e) {
const t = parseFloat(e);
return isNaN(t) ? 0 : t * 4;
}
parseTailwindOpacity(e) {
const t = parseFloat(e);
return isNaN(t) ? 0 : t * 0.01;
}
parseTailwindScale(e) {
const t = parseFloat(e);
return isNaN(t) ? 1 : t * 0.01;
}
parseTailwindRotate(e) {
const t = parseFloat(e);
return isNaN(t) ? 0 : t;
}
parseTailwindBlur(e) {
const t = parseFloat(e);
return isNaN(t) ? 0 : t * 4;
}
parseTailwindGrayscale(e) {
const t = parseFloat(e);
return isNaN(t) ? 0 : t * 0.01;
}
parseTailwindSkew(e) {
const t = parseFloat(e);
return isNaN(t) ? 0 : t;
}
parseTailwindPerspective(e) {
const t = parseFloat(e);
return isNaN(t) ? 0 : t;
}
}
class D {
constructor(e, t, s) {
d(this, "timelinePresets");
d(this, "mediaQueries");
d(this, "timelineParser");
d(this, "valueParser");
this.timelinePresets = e, this.mediaQueries = t, this.valueParser = new V(s), this.timelineParser = new P(this.valueParser);
}
parse(e) {
if (!e)
return null;
const t = this.parseBreakpoints(e), s = this.getActiveConfig(t);
if (!s)
return null;
const r = e.match(
/transition-duration-(\d+)/
);
r && (s.transitionDuration = parseInt(
r[1],
10
));
const n = e.match(
/transition-easing-([a-zA-Z-]+)/
);
return n && (s.transitionEasing = n[1]), s;
}
parseBreakpoints(e) {
const t = {};
return e.trim().split(/(?=@)/).forEach((r) => {
const n = r.trim();
if (!n)
return;
let o = "default", a = n;
if (n.startsWith("@")) {
const i = n.indexOf(":");
i > -1 && (o = n.substring(1, i), a = n.substring(i + 1));
}
t[o] || (t[o] = { from: {}, to: {}, breakpoint: o }), this.processConfig(o, a, t);
}), t;
}
processConfig(e, t, s) {
if (s[e] || (s[e] = {
from: {},
to: {},
breakpoint: e
}), t.includes(";") && (t.includes("from:") || t.includes("via-") || t.includes("to:"))) {
s[e].timeline = this.timelineParser.parse(t);
return;
}
(t.includes(";") ? t.split(";").map((o) => o.trim()) : [t.trim()]).forEach((o) => {
o && this.parsePart(o, s[e]);
});
}
parsePart(e, t) {
try {
e.split(/\s+(?=(?:from|to|timeline|preset):)/).forEach((r) => {
const n = r.trim();
if (n.startsWith("from:")) {
const o = n.substring(5);
this.parseProps(o, t.from);
} else if (n.startsWith("to:")) {
const o = n.substring(3);
this.parseProps(o, t.to);
} else if (n.startsWith("timeline:")) {
const o = n.substring(9);
t.timeline = this.timelineParser.parse(o);
} else if (n.startsWith("preset:")) {
const o = n.substring(7).trim(), a = this.timelinePresets.get(o);
a ? t.timeline = a : console.warn(`ScrollyMotion: Unknown preset: ${o}`);
}
});
} catch (s) {
console.error(
`ScrollyMotion: Failed to parse animation part: "${e}"`,
s
);
}
}
parseProps(e, t) {
try {
e.split("|").forEach((r) => {
if (r.startsWith("letter-spacing")) {
const o = r.substring(15);
t["letter-spacing"] = this.valueParser.parse(
"letter-spacing",
o
);
return;
}
const n = r.indexOf("-");
if (n > 0) {
const o = r.substring(0, n);
let a = r.substring(n + 1);
a.startsWith("-") && (a = a), o && a !== void 0 && (t[o] = this.valueParser.parse(o, a));
}
});
} catch (s) {
console.error(
`ScrollyMotion: Failed to parse properties: "${e}"`,
s
);
}
}
getActiveConfig(e) {
for (const t of A)
if (e[t]) {
const s = this.mediaQueries.get(t);
if (s && s.matches)
return e[t];
}
return e.default || null;
}
}
class B {
constructor(e) {
d(this, "timelineParser");
d(this, "valueParser");
this.valueParser = new V(e), this.timelineParser = new P(this.valueParser);
}
parse(e) {
if (!e)
return null;
try {
const t = e.match(
/transition-duration-(\d+)/
), s = e.match(
/transition-easing-([a-zA-Z-]+)/
), r = e.match(/^\[([^\]]+)\]:/);
if (!r)
return null;
let n = r[1];
n.startsWith("&") && (n = n.substring(1));
const o = e.substring(r[0].length), a = {
selector: n,
from: {},
to: {},
staggerDelay: 0.1,
breakpoint: "default",
transitionDuration: t ? parseInt(t[1], 10) : void 0,
transitionEasing: s ? s[1] : void 0
};
if (o.includes(";") && (o.includes("from:") || o.includes("via-") || o.includes("to:")) || o.includes("via-"))
this.processSection("timeline", o, a);
else if (o.startsWith("timeline:")) {
const l = o.substring(9);
this.processSection("timeline", l, a);
} else {
const l = o.split(":");
let c = "", m = "";
l.forEach((h) => {
h === "from" || h === "to" ? (c && m && this.processSection(c, m, a), c = h, m = "") : (m && (m += ":"), m += h);
}), c && m && this.processSection(c, m, a);
}
return a;
} catch (t) {
return console.error(
`ScrollyMotion: Failed to parse stagger animation: "${e}"`,
t
), null;
}
}
parseMultiBreakpoint(e) {
var t;
try {
const s = {}, r = /(@[^:]+:)/g, n = e.split(r).filter(Boolean);
let o = "default";
for (let a = 0; a < n.length; a++) {
const i = n[a].trim();
if (i.startsWith("@") && i.endsWith(":")) {
o = i.slice(1, -1);
const l = (t = n[a + 1]) == null ? void 0 : t.trim();
if (l) {
const c = this.parse(l);
c && (s[o] = c), a++;
}
} else {
const l = this.parse(i);
l && (s.default = l);
}
}
return s;
} catch (s) {
return console.error(
`ScrollyMotion: Failed to parse multi-breakpoint stagger animation: "${e}"`,
s
), {};
}
}
processSection(e, t, s) {
if (e === "from" || e === "to")
t.split("|").forEach((n) => {
if (n.startsWith("stagger-"))
s.staggerDelay = parseFloat(n.substring(8)) || 0.1;
else {
const o = n.indexOf("-");
if (o > 0) {
const a = n.substring(0, o), i = n.substring(o + 1);
if (a && i !== void 0) {
const l = e === "from" ? s.from : s.to;
l[a] = this.valueParser.parse(a, i);
}
}
}
});
else if (e === "timeline") {
let r = t, n = 0.1, o;
t.includes(";") ? o = t.split(";") : o = t.split(/\s+(?=(?:from:|via-|to:))/);
const a = [];
o.forEach((i) => {
const l = i.trim();
if (l.includes("|stagger-")) {
const c = l.split("|"), m = c.find((p) => p.startsWith("stagger-"));
m && (n = parseFloat(m.substring(8)) || 0.1);
const h = c.filter(
(p) => !p.startsWith("stagger-")
);
a.push(h.join("|"));
} else
a.push(l);
}), s.staggerDelay = n, r = a.join("; "), s.timeline = this.timelineParser.parse(r);
}
}
}
class R {
constructor(e, t, s) {
d(this, "animationParser");
d(this, "staggerParser");
this.animationParser = new D(
e,
t,
s
), this.staggerParser = new B(s);
}
parseAnimation(e) {
try {
return this.animationParser.parse(e);
} catch (t) {
return console.error("Failed to parse animation:", t), null;
}
}
parseStaggerAnimation(e, t = "default") {
try {
return this.staggerParser.parse(e);
} catch (s) {
return console.error("Failed to parse stagger animation:", s), null;
}
}
parseMultiBreakpointStagger(e) {
try {
return this.staggerParser.parseMultiBreakpoint(e);
} catch (t) {
return console.error("Failed to parse multi-breakpoint stagger animation:", t), {};
}
}
}
class X {
/**
* Update regular animation based on scroll progress
*/
updateAnimation(e, t) {
if (!e._animationConfig)
return;
const { from: s, to: r, timeline: n } = e._animationConfig;
if (n && n.length > 0) {
const i = this.calculateTimelineValues(n, t);
this.applyAnimationValues(e, i);
return;
}
const o = {};
(/* @__PURE__ */ new Set([...Object.keys(s), ...Object.keys(r)])).forEach((i) => {
const l = s[i], c = r[i];
if (l !== void 0 && c !== void 0)
if (typeof l == "number" && typeof c == "number")
o[i] = l + (c - l) * t;
else if (typeof l == "string" && typeof c == "string") {
const m = l.match(/^(-?[\d.]+)([a-z%]+)$/i), h = c.match(/^(-?[\d.]+)([a-z%]+)$/i);
if (m && h && m[2] === h[2]) {
const p = parseFloat(m[1]), f = parseFloat(h[1]), g = p + (f - p) * t;
o[i] = g + m[2];
} else
o[i] = t < 0.5 ? l : c;
} else
o[i] = t < 0.5 ? l : c;
else if (l !== void 0 && c === void 0) {
const m = i === "opacity" ? 1 : 0;
typeof l == "number" ? o[i] = l + (m - l) * t : o[i] = l;
} else
l === void 0 && c !== void 0 && (typeof c == "number" ? o[i] = 0 + (c - 0) * t : o[i] = t > 0 ? c : void 0);
}), this.applyAnimationValues(e, o);
}
/**
* Calculate timeline values for a given progress
*/
calculateTimelineValues(e, t) {
const s = {};
let r = null, n = null;
for (let o = 0; o < e.length; o++) {
const a = e[o];
if (t >= a.at)
r = a, n = e[o + 1] || null;
else
break;
}
if (r || (r = e[0], n = e[1] || null), n && t > r.at) {
const o = (t - r.at) / (n.at - r.at);
(/* @__PURE__ */ new Set([
...Object.keys(r.properties),
...Object.keys(n.properties)
])).forEach((i) => {
const l = r.properties[i], c = n.properties[i];
if (l !== void 0 && c !== void 0)
if (typeof l == "number" && typeof c == "number")
s[i] = l + (c - l) * o;
else if (typeof l == "string" && typeof c == "string") {
const m = l.match(/^(-?[\d.]+)([a-z%]+)$/i), h = c.match(/^(-?[\d.]+)([a-z%]+)$/i);
if (m && h && m[2] === h[2]) {
const p = parseFloat(m[1]), f = parseFloat(h[1]), g = p + (f - p) * o;
s[i] = g + m[2];
} else
s[i] = o < 0.5 ? l : c;
} else
s[i] = o < 0.5 ? l : c;
else
l !== void 0 ? s[i] = l : c !== void 0 && (s[i] = o > 0 ? c : void 0);
});
} else
Object.assign(s, r.properties);
return s;
}
/**
* Update stagger animation for multiple children
*/
updateStaggerAnimation(e, t) {
if (!e._staggerConfig || e._staggerChildren.length === 0)
return;
const { from: s, to: r, staggerDelay: n, timeline: o } = e._staggerConfig, a = e._staggerChildren.length, i = (a - 1) * n;
e._staggerChildren.forEach((l, c) => {
let m = 0;
if (t > 0) {
const p = c * n / (1 + i), f = p + 1 / (1 + i);
t >= p && (m = Math.min(
1,
(t - p) / (f - p)
));
} else if (t < 0 && !e._once) {
const f = (a - 1 - c) * n / (1 + i), g = f + 1 / (1 + i), y = Math.abs(t);
y >= f ? m = 1 - Math.min(
1,
(y - f) / (g - f)
) : m = 1;
}
let h = {};
o && o.length > 0 ? h = this.calculateTimelineValues(o, m) : (/* @__PURE__ */ new Set([...Object.keys(s), ...Object.keys(r)])).forEach((f) => {
const g = s[f], y = r[f];
if (g !== void 0 && y !== void 0)
typeof g == "number" && typeof y == "number" ? h[f] = g + (y - g) * m : h[f] = m < 0.5 ? g : y;
else if (g !== void 0) {
const b = f === "opacity" ? 1 : 0;
typeof g == "number" ? h[f] = g + (b - g) * m : h[f] = g;
} else
y !== void 0 && (typeof y == "number" ? h[f] = 0 + (y - 0) * m : h[f] = m > 0 ? y : void 0);
}), this.applyAnimationValues(l, h);
});
}
/**
* Apply animation values to an element
*/
applyAnimationValues(e, t) {
const s = [], r = [];
let n = !1, o = !1;
if (Object.keys(t).forEach((a) => {
const i = t[a];
if (i != null)
if (a === "opacity")
e.style.opacity = i.toString();
else if (a === "translateX") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
s.push(`translateX(${l})`), n = !0;
} else if (a === "translateY") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
s.push(`translateY(${l})`), n = !0;
} else if (a === "translateZ") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
s.push(`translateZ(${l})`), n = !0;
} else if (a === "scale")
s.push(`scale(${i})`), n = !0;
else if (a === "scaleX")
s.push(`scaleX(${i})`), n = !0;
else if (a === "scaleY")
s.push(`scaleY(${i})`), n = !0;
else if (a === "rotate") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`rotate(${l})`), n = !0;
} else if (a === "rotateX") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`rotateX(${l})`), n = !0;
} else if (a === "rotateY") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`rotateY(${l})`), n = !0;
} else if (a === "rotateZ") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`rotateZ(${l})`), n = !0;
} else if (a === "skewX") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`skewX(${l})`), n = !0;
} else if (a === "skewY") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`skewY(${l})`), n = !0;
} else if (a === "blur") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
r.push(`blur(${l})`), o = !0;
} else if (a === "grayscale")
r.push(`grayscale(${i})`), o = !0;
else if (a === "perspective") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
e.style.perspective = l;
} else if (a === "letter-spacing") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
e.style.letterSpacing = l;
} else
try {
e.style[a] = i;
} catch (l) {
console.error(`Failed to apply style ${a}: ${i}`, l);
}
}), n) {
const a = s.join(" ");
e.style.transform = a;
}
if (o) {
const a = r.join(" ");
e.style.filter = a;
}
}
}
class Q {
constructor() {
d(this, "themedElements", /* @__PURE__ */ new Map());
d(this, "body", document.body);
}
registerElement(e, t) {
this.themedElements.set(e, { theme: t, inView: !1 });
}
updateElementViewStatus(e, t) {
this.themedElements.has(e) && (this.themedElements.get(e).inView = t), this.updateBodyTheme();
}
updateBodyTheme() {
const e = Array.from(this.themedElements.values()).filter((t) => t.inView).map((t) => t.theme);
e.length > 0 ? this.body.setAttribute(
"data-theme",
e[e.length - 1]
) : this.body.removeAttribute("data-theme");
}
}
const Z = /* @__PURE__ */ new Set([
"translateX",
"translateY",
"translateZ",
"scale",
"scaleX",
"scaleY",
"rotate",
"rotateX",
"rotateY",
"rotateZ",
"skewX",
"skewY",
"perspective"
]), U = /* @__PURE__ */ new Set(["blur", "grayscale"]);
function q(u) {
const e = /* @__PURE__ */ new Set();
return u.timeline ? u.timeline.forEach((t) => {
Object.keys(t.properties).forEach((s) => e.add(s));
}) : ("from" in u && Object.keys(u.from).forEach((t) => e.add(t)), "to" in u && Object.keys(u.to).forEach((t) => e.add(t))), e;
}
function _(u, e = 200, t = "linear") {
const s = q(u), r = /* @__PURE__ */ new Set();
let n = !1, o = !1;
return s.forEach((a) => {
Z.has(a) ? n = !0 : U.has(a) ? o = !0 : r.add(
`${a.replace(/([A-Z])/g, "-$1").toLowerCase()} ${e}ms ${t}`
);
}), n && r.add(`transform ${e}ms ${t}`), o && r.add(`filter ${e}ms ${t}`), Array.from(r).join(", ");
}
class K {
constructor(e, t, s, r, n) {
d(this, "elements");
d(this, "selector");
d(this, "config");
d(this, "parser");
d(this, "animation");
d(this, "themeManager");
d(this, "mediaQueries");
d(this, "intersectionObserver");
d(this, "activeElements", /* @__PURE__ */ new Set());
this.elements = /* @__PURE__ */ new Map(), this.selector = e.selector || "[data-scroll], [data-animation]", this.config = e, this.parser = t, this.animation = s, this.themeManager = r, this.mediaQueries = n, this.intersectionObserver = new IntersectionObserver(
this.handleIntersection.bind(this),
{
rootMargin: "0px",
threshold: 0
}
);
}
handleIntersection(e) {
e.forEach((t) => {
const s = this.elements.get(t.target);
s && (t.isIntersecting ? this.activeElements.add(s) : this.activeElements.delete(s));
});
}
discoverElements() {
document.querySelectorAll(this.selector).forEach((t) => {
this.elements.has(t) || (this.elements.set(t, t), this.intersectionObserver.observe(t));
});
}
measureElements() {
const e = window.innerHeight;
this.elements.forEach((t) => {
this._parseElementConfig(t, e), this._setupAnimationConfig(t);
});
}
_applyInitialVisualState(e) {
if (e._animationConfig) {
let t = {};
if (e._animationConfig.timeline && e._animationConfig.timeline.length > 0) {
const s = e._animationConfig.timeline[0];
s.at === 0 && (t = s.properties);
} else
e._animationConfig.from && Object.keys(e._animationConfig.from).length > 0 && (t = e._animationConfig.from);
Object.keys(t).length > 0 && (this.animation.applyAnimationValues(e, t), e.style.setProperty("--element-progress", "0.000"));
}
if (e._staggerConfig) {
let t = {};
if (e._staggerConfig.timeline && e._staggerConfig.timeline.length > 0) {
const s = e._staggerConfig.timeline[0];
s.at === 0 && (t = s.properties);
} else
e._staggerConfig.from && Object.keys(e._staggerConfig.from).length > 0 && (t = e._staggerConfig.from);
if (Object.keys(t).length > 0) {
let s = [];
if (e._staggerConfig.selector.startsWith(">")) {
const r = e._staggerConfig.selector.substring(1);
s = Array.from(e.children).filter(
(n) => n.matches(r)
);
} else
s = Array.from(
e.querySelectorAll(e._staggerConfig.selector)
);
s.forEach((r) => {
this.animation.applyAnimationValues(r, t);
}), e.style.setProperty("--element-progress", "0.000");
}
}
}
_parseElementConfig(e, t) {
const s = window.scrollY || window.pageYOffset, r = e.getBoundingClientRect(), n = s + r.top, o = r.height, a = e.hasAttribute("data-scroll"), i = e.hasAttribute("data-animation"), c = (!a && i ? Object.entries(W).map(([g, y]) => `${g}:${y}`).join(";") : e.getAttribute("data-scroll") || "").split(/\s*;\s*/).reduce((g, y) => {
const [b, z] = y.split(/\s*:\s*/);
if (!b)
return g;
let w = z;
return w === "true" || w === "false" ? w = w === "true" : isNaN(w) || (w = parseFloat(w)), g[b] = w, g;
}, {}), m = M(
c.enter != null ? c.enter : this.config.defaultEnter,
t
), h = M(c.exit != null ? c.exit : 0, t);
let p;
if (c.exit != null && c.distance == null) {
const g = n - (t - m);
p = n + o - h - g;
} else
p = M(c.distance != null ? c.distance : o, t);
if (e._enterAt = n - (t - m), e._distance = p, e._exitAt = n + o - h, e._theme = c.theme, c.theme && this.themeManager.registerElement(e, c.theme), e._once = c.once, e._enterClassNames = E(
c.enterClass || c.class,
C.enterClassNames
), e._leaveClassNames = E(
c.leaveClass,
C.leaveClassNames
), e._hasEnteredOnce = !1, !e._wcElements) {
const g = E(c.wc, []);
e._wcElements = g.flatMap(
(y) => Array.from(e.querySelectorAll(y))
);
}
e._targetProgress = 0, e._currentProgress = 0;
const f = e.getAttribute("data-animation");
if (f) {
const g = f.includes(":[");
f.includes("]:") ? (e._multiStaggerConfig = this.parser.parseMultiBreakpointStagger(f), e._staggerConfig = this.getActiveStaggerConfig(e._multiStaggerConfig), e._animationConfig = null) : g ? (e._staggerConfig = this.parser.parseStaggerAnimation(f), e._animationConfig = null) : (e._animationConfig = this.parser.parseAnimation(f), e._staggerConfig = null);
} else
e._animationConfig = null, e._staggerConfig = null;
e._animeInstance = null, e._staggerChildren = [], this._applyInitialVisualState(e);
}
_setupAnimationConfig(e) {
if (e._staggerConfig) {
const t = e._staggerConfig;
if (!e._staggerChildren || e._staggerChildren.length === 0) {
let s = [];
if (t.selector.startsWith(">")) {
const r = t.selector.substring(1);
s = Array.from(e.children).filter(
(n) => n.matches(r)
);
} else
s = Array.from(
e.querySelectorAll(t.selector)
);
e._staggerChildren = s, s.forEach((r) => {
const n = _(
t,
t.transitionDuration,
t.transitionEasing
);
n && (r.style.transition = n);
});
}
}
if (e._animationConfig) {
const t = e._animationConfig, s = _(
t,
t.transitionDuration,
t.transitionEasing
);
s && (e.style.transition = s);
}
}
getElements() {
return Array.from(this.elements.values());
}
getActiveElements() {
return Array.from(this.activeElements);
}
destroy() {
this.intersectionObserver.disconnect(), this.elements.clear();
}
getActiveStaggerConfig(e) {
if (!e)
return null;
for (const t of A)
if (e[t]) {
const s = this.mediaQueries.get(t);
if (s && s.matches)
return e[t];
}
return e.default || null;
}
}
class T {
constructor() {
d(this, "events");
this.events = /* @__PURE__ */ new Map();
}
on(e, t) {
this.events.has(e) || this.events.set(e, /* @__PURE__ */ new Set()), this.events.get(e).add(t);
}
off(e, t) {
this.events.has(e) && this.events.get(e).delete(t);
}
emit(e, ...t) {
this.events.has(e) && this.events.get(e).forEach((s) => {
try {
s(...t);
} catch (r) {
console.error(
`ScrollyMotion: Error in event handler for "${e}"`,
r
);
}
});
}
destroy() {
this.events.clear();
}
}
class G {
constructor() {
d(this, "plugins");
this.plugins = /* @__PURE__ */ new Map();
}
register(e) {
if (this.plugins.has(e.name)) {
console.warn(
`ScrollyMotion: Plugin "${e.name}" is already registered.`
);
return;
}
this.plugins.set(e.name, e);
}
getPlugin(e) {
return this.plugins.get(e);
}
parse(e, t) {
for (const s of this.plugins.values()) {
const r = s.parse(e, t);
if (r !== void 0)
return r;
}
}
destroy() {
this.plugins.clear();
}
}
class H {
constructor(...e) {
d(this, "prevScrollY");
d(this, "ticking");
d(this, "body");
d(this, "onResize");
d(this, "mediaQueries");
d(this, "modules");
d(this, "parser");
d(this, "animation");
d(this, "themeManager");
d(this, "elementManager");
d(this, "eventManager");
d(this, "pluginManager");
const { modules: t, config: s } = this.parseConstructorArgs(e);
this.modules = t, this.eventManager = new T(), this.pluginManager = new G();
const { isValid: r, errors: n, warnings: o, sanitizedConfig: a } = Y(s);
if (o.length > 0 && o.forEach((l) => console.warn(`ScrollyMotion: ${l}`)), !r)
throw n.forEach((l) => console.error(`ScrollyMotion: ${l}`)), new Error("ScrollyMotion: Invalid configuration.");
this.prevScrollY = 0, this.ticking = !1, this.updateScroll = this.updateScroll.bind(this), this.onScroll = this.onScroll.bind(this), this.onResize = $(() => {
this.elementManager.measureElements(), this.updateScroll();
}, 200), this.body = document.body, this.mediaQueries = L(
a.breakpoints || j.breakpoints
);
const i = this.initializePresets(a.presets);
this.parser = new R(
i,
this.mediaQueries,
this.pluginManager
), this.animation = new X(), this.themeManager = new Q(), this.elementManager = new K(
a,
this.parser,
this.animation,
this.themeManager,
this.mediaQueries
), this.initializeModules(), this.init();
}
parseConstructorArgs(e) {
const t = [];
let s = {};
if (e.length === 0)
return { modules: t, config: s };
const r = e[e.length - 1];
if (r && typeof r == "object" && !r.name && // modules have a name property
!Array.isArray(r) && typeof r != "function") {
s = r;
for (let o = 0; o < e.length - 1; o++) {
const a = e[o];
if (typeof a == "function") {
const i = a();
i && i.name && t.push(i);
} else
a && typeof a == "object" && a.name && t.push(a);
}
} else if (e.length === 1 && typeof e[0] == "object" && !e[0].name && typeof e[0] != "function")
s = e[0];
else
for (const o of e)
if (typeof o == "function") {
const a = o();
a && a.name && t.push(a);
} else
o && typeof o == "object" && o.name && t.push(o);
return console.log(
"🔧 ScrollyMotion: Parsed modules:",
t.map((o) => o.name)
), { modules: t, config: s };
}
initializeModules() {
this.modules.forEach((e) => {
e.init && e.init(this);
});
}
hasModule(e) {
return this.modules.some((t) => t.name === e);
}
destroy() {
this.modules.forEach((e) => {
e.destroy && e.destroy();
}), window.removeEventListener("resize", this.onResize), window.removeEventListener("scroll", this.onScroll), this.elementManager.destroy(), this.eventManager.destroy(), this.pluginManager.destroy();
}
init() {
const e = () => {
this.elementManager.discoverElements();
const t = this.elementManager.getElements();
t.length > 0 && (this.elementManager.measureElements(), t.forEach((s) => {
s._currentProgress = 0, s._targetProgress = 0, s._hasStartedAnimating = !1, s.style.setProperty("--element-progress", "0.000");
}), this.updateScroll(), setTimeout(() => {
this.updateScroll();
}, 50));
};
document.readyState === "loading" ? window.addEventListener("DOMContentLoaded", e) : e(), window.addEventListener("resize", this.onResize), window.addEventListener("scroll", this.onScroll, { passive: !0 });
}
onScroll() {
this.ticking || (window.requestAnimationFrame(this.updateScroll), this.ticking = !0);
}
updateScroll() {
const e = window.scrollY || window.pageYOffset;
let t = "up";
e >= 300 && (t = e > this.prevScrollY ? "down" : "up"), this.body.setAttribute("data-scroll-direction", t), this.prevScrollY = e, this.elementManager.getActiveElements().forEach((s) => {
const { _enterAt: r, _distance: n, _exitAt: o, _once: a } = s, i = Math.min(
1,
Math.max(0, (e - r) / n)
);
s._targetProgress = i, s._currentProgress = i, s.style.setProperty("--element-progress", i.toFixed(3));
const l = i > 0, c = e > o, m = l && !c;
s._theme && this.hasModule("themes") && this.themeManager.updateElementViewStatus(s, m), m ? (s._hasEnteredOnce || this.eventManager.emit("elementEnter", s), s._hasEnteredOnce = !0, s._enterClassNames.forEach((h) => s.classList.add(h)), s._leaveClassNames.forEach((h) => s.classList.remove(h))) : (s._hasEnteredOnce && this.eventManager.emit("elementLeave", s), a && s._hasEnteredOnce || (s._enterClassNames.forEach((h) => s.classList.remove(h)), s._leaveClassNames.forEach((h) => s.classList.add(h)))), this.hasModule("webcomponents") && s._wcElements.forEach((h) => {
const p = h;
if (typeof p.progress == "function" && p._lastProgress !== i && (p.progress(i), p._lastProgress = i), typeof p.enter == "function") {
const f = m;
p._lastInView !== f && (f && typeof p.enter == "function" && p.enter(), !f && typeof p.leave == "function" && p.leave(), p._lastInView = f);
}
}), this.modules.forEach((h) => {
h.updateElement && h.updateElement(s, i);
});
}), this.ticking = !1;
}
on(e, t) {
this.eventManager.on(e, t);
}
registerPlugin(e) {
this.pluginManager.register(e);
}
initializePresets(e = {}) {
const t = /* @__PURE__ */ new Map();
return Object.entries(e).forEach(([s, r]) => {
t.set(s, r);
}), t;
}
getMetrics() {
const e = this.elementManager.getElements(), t = e.filter(
(n) => n._animationConfig || n._staggerConfig
).length, s = e.length * 0.5 + t * 1.2, r = "transform" in document.createElement("div").style;
return {
fps: 60,
activeElements: t,
memoryUsage: s,
gpuAccelerated: r
};
}
// Public API for getting loaded modules
getModules() {
return [...this.modules];
}
// Public API for checking if a module is loaded
hasModuleLoaded(e) {
return this.hasModule(e);
}
// ScrollyMotionCore interface methods required by modules
getElements() {
return this.elementManager.getElements();
}
getActiveElements() {
return this.elementManager.getActiveElements();
}
emit(e, ...t) {
this.eventManager.emit(e, ...t);
}
}
class J {
constructor(e) {
d(this, "name", "timeline");
}
init(e) {
}
destroy() {
}
updateElement(e, t) {
e._animationConfig && this.updateAnimation(e, t), e._staggerConfig && e._staggerChildren.length > 0 && this.updateStaggerAnimation(e, t);
}
/**
* Update regular animation based on scroll progress
*/
updateAnimation(e, t) {
if (!e._animationConfig)
return;
const { from: s, to: r, timeline: n } = e._animationConfig;
if (n && n.length > 0) {
const i = this.calculateTimelineValues(n, t);
this.applyAnimationValues(e, i);
return;
}
const o = {};
(/* @__PURE__ */ new Set([...Object.keys(s), ...Object.keys(r)])).forEach((i) => {
const l = s[i], c = r[i];
if (l !== void 0 && c !== void 0)
if (typeof l == "number" && typeof c == "number")
o[i] = l + (c - l) * t;
else if (typeof l == "string" && typeof c == "string") {
const m = l.match(/^(-?[\d.]+)([a-z%]+)$/i), h = c.match(/^(-?[\d.]+)([a-z%]+)$/i);
if (m && h && m[2] === h[2]) {
const p = parseFloat(m[1]), f = parseFloat(h[1]), g = p + (f - p) * t;
o[i] = g + m[2];
} else
o[i] = t < 0.5 ? l : c;
} else
o[i] = t < 0.5 ? l : c;
else if (l !== void 0 && c === void 0) {
const m = i === "opacity" ? 1 : 0;
typeof l == "number" ? o[i] = l + (m - l) * t : o[i] = l;
} else
l === void 0 && c !== void 0 && (typeof c == "number" ? o[i] = 0 + (c - 0) * t : o[i] = t > 0 ? c : void 0);
}), this.applyAnimationValues(e, o);
}
/**
* Calculate timeline values for a given progress
*/
calculateTimelineValues(e, t) {
const s = {};
let r = null, n = null;
for (let o = 0; o < e.length; o++) {
const a = e[o];
if (t >= a.at)
r = a, n = e[o + 1] || null;
else
break;
}
if (r || (r = e[0], n = e[1] || null), n && t > r.at) {
const o = (t - r.at) / (n.at - r.at);
(/* @__PURE__ */ new Set([
...Object.keys(r.properties),
...Object.keys(n.properties)
])).forEach((i) => {
const l = r.properties[i], c = n.properties[i];
if (l !== void 0 && c !== void 0)
if (typeof l == "number" && typeof c == "number")
s[i] = l + (c - l) * o;
else if (typeof l == "string" && typeof c == "string") {
const m = l.match(/^(-?[\d.]+)([a-z%]+)$/i), h = c.match(/^(-?[\d.]+)([a-z%]+)$/i);
if (m && h && m[2] === h[2]) {
const p = parseFloat(m[1]), f = parseFloat(h[1]), g = p + (f - p) * o;
s[i] = g + m[2];
} else
s[i] = o < 0.5 ? l : c;
} else
s[i] = o < 0.5 ? l : c;
else
l !== void 0 ? s[i] = l : c !== void 0 && (s[i] = o > 0 ? c : void 0);
});
} else
Object.assign(s, r.properties);
return s;
}
/**
* Update stagger animation for multiple children
*/
updateStaggerAnimation(e, t) {
if (!e._staggerConfig || e._staggerChildren.length === 0)
return;
const { from: s, to: r, staggerDelay: n, timeline: o } = e._staggerConfig, a = e._staggerChildren.length, i = (a - 1) * n;
e._staggerChildren.forEach((l, c) => {
let m = 0;
if (t > 0) {
const p = c * n / (1 + i), f = p + 1 / (1 + i);
t >= p && (m = Math.min(
1,
(t - p) / (f - p)
));
} else if (t < 0 && !e._once) {
const f = (a - 1 - c) * n / (1 + i), g = f + 1 / (1 + i), y = Math.abs(t);
y >= f ? m = 1 - Math.min(
1,
(y - f) / (g - f)
) : m = 1;
}
let h = {};
o && o.length > 0 ? h = this.calculateTimelineValues(o, m) : (/* @__PURE__ */ new Set([...Object.keys(s), ...Object.keys(r)])).forEach((f) => {
const g = s[f], y = r[f];
if (g !== void 0 && y !== void 0)
typeof g == "number" && typeof y == "number" ? h[f] = g + (y - g) * m : h[f] = m < 0.5 ? g : y;
else if (g !== void 0) {
const b = f === "opacity" ? 1 : 0;
typeof g == "number" ? h[f] = g + (b - g) * m : h[f] = g;
} else
y !== void 0 && (typeof y == "number" ? h[f] = 0 + (y - 0) * m : h[f] = m > 0 ? y : void 0);
}), this.applyAnimationValues(l, h);
});
}
/**
* Apply animation values to an element
*/
applyAnimationValues(e, t) {
const s = [], r = [];
let n = !1, o = !1;
if (Object.keys(t).forEach((a) => {
const i = t[a];
if (i != null)
if (a === "opacity")
e.style.opacity = i.toString();
else if (a === "translateX") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
s.push(`translateX(${l})`), n = !0;
} else if (a === "translateY") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
s.push(`translateY(${l})`), n = !0;
} else if (a === "translateZ") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
s.push(`translateZ(${l})`), n = !0;
} else if (a === "scale")
s.push(`scale(${i})`), n = !0;
else if (a === "scaleX")
s.push(`scaleX(${i})`), n = !0;
else if (a === "scaleY")
s.push(`scaleY(${i})`), n = !0;
else if (a === "rotate") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`rotate(${l})`), n = !0;
} else if (a === "rotateX") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`rotateX(${l})`), n = !0;
} else if (a === "rotateY") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`rotateY(${l})`), n = !0;
} else if (a === "rotateZ") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`rotateZ(${l})`), n = !0;
} else if (a === "skewX") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`skewX(${l})`), n = !0;
} else if (a === "skewY") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}deg`;
s.push(`skewY(${l})`), n = !0;
} else if (a === "blur") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
r.push(`blur(${l})`), o = !0;
} else if (a === "grayscale")
r.push(`grayscale(${i})`), o = !0;
else if (a === "perspective") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
e.style.perspective = l;
} else if (a === "letter-spacing") {
const l = typeof i == "string" && i.match(/[a-z%]/i) ? i : `${i}px`;
e.style.letterSpacing = l;
} else
try {
e.style[a] = i;
} catch (l) {
console.error(`Failed to apply style ${a}: ${i}`, l);
}
}), n) {
const a = s.join(" ");
e.style.transform = a;
}
if (o) {
const a = r.join(" ");
e.style.filter = a;
}
}
}
const S = (u) => new J(u);
class k {
constructor() {
d(this, "name", "stagger");
}
init(e) {
}
destroy() {
}
parseElement(e) {
const t = e.getAttribute("data-animation");
if (!t)
return;
const s = t.match(/\[([^\]]+)\]:/);
if (!s)
return;
const r = s[1], n = Array.from(
e.querySelectorAll(r)
);
if (n.length === 0)
return;
const o = this.parseStaggerAnimation(t, r);
if (!o)
return;
const a = e;
a._staggerConfig = o, a._staggerChildren = n;
}
updateElement(e, t) {
}
/**
* Parse stagger animation configuration from data-animation attribute
*/
parseStaggerAnimation(e, t) {
try {
const r = e.replace(`[${t}]:`, "").split(/\s*;\s*/), n = {
selector: t,
from: {},
to: {},
staggerDelay: 0.1
// default
};
for (const o of r) {
const a = o.trim();
if (a)
if (a.startsWith("from:"))
n.from = this.parseAnimationProperties(a.substring(5));
else if (a.startsWith("to:")) {
const i = this.parseAnimationProperties(
a.substring(3)
);
n.to = i.properties, n.staggerDelay = i.staggerDelay || n.staggerDelay;
} else
a.startsWith("timeline:") && (n.timeline = this.parseTimelineProperties(
a.substring(9)
));
}
return n;
} catch (s) {
return console.warn("Failed to parse stagger animation:", s), null;
}
}
/**
* Parse animation properties from a property string
*/
parseAnimationProperties(e) {
const t = {};
let s;
const r = e.split("|");
for (const n of r) {
const o = n.trim();
if (!o)
continue;
if (o.startsWith("stagger-")) {
s = parseFloat(o.substring(8));
continue;
}
const a = o.match(/^([a-zA-Z-]+)-(.+)$/);
if (!a)
continue;
const [, i, l] = a;
t[i] = this.parseValue(l);
}
return { properties: t, staggerDelay: s };
}
/**
* Parse timeline properties (simplified version)
*/
parseTimelineProperties(e) {
const t = e.split(";"), s = [];
for (const r of t) {
const n = r.trim();
if (!n)
continue;
let o = 0, a = "";
if (n.startsWith("from:"))
o = 0, a = n.substring(5);
else if (n.startsWith("to:"))
o = 1, a = n.substring(3);
else if (n.includes("via-")) {
const i = n.match(/via-(\d+)%:(.+)/);
i && (o = parseInt(i[1]) / 100, a = i[2]);
}
if (a) {
const { properties: i } = this.parseAnimationProperties(a);
s.push({ at: o, properties: i });
}
}
return s;
}
/**
* Parse a single value (number, string with units, etc.)
*/
parseValue(e) {
const t = e.match(/^\[(.+)\]$/);
if (t) {
const r = t[1], n = parseFloat(r);
return !isNaN(n) && r === n.toString() ? n : r;
}
if (e.startsWith("-")) {
const r = e.substring(1), n = this.parseValue(r);
return typeof n == "number" ? -n : `-${n}`;
}
const s = parseFloat(e);
return isNaN(s) ? e : s;
}
/**
* Get stagger children for an element
*/
getStaggerChildren(e, t) {
return Array.from(e.querySelectorAll(t));
}
/**
* Update stagger children for an element (useful for dynamic content)
*/
updateStaggerChildren(e) {
if (!e._staggerConfig)
return;
const t = e._staggerConfig.selector, s = this.getStaggerChildren(e, t);
e._staggerChildren = s;
}
}
const x = () => new k();
class ee {
constructor() {
d(this, "name", "themes");
d(this, "scrollyMotion", null);
d(this, "currentTheme", null);
d(this, "themeElements", /* @__PURE__ */ new Set());
}
init(e) {
this.scrollyMotion = e;
}
destroy() {
this.themeElements.clear(), this.scrollyMotion = null;
}
parseElement(e) {
const t = e.getAttribute("data-scroll");
if (!t)
return;
const s = t.match(/theme:\s*([^;]+)/);
if (!s)
return;
const r = s[1].trim(), n = e;
n._theme = r, this.themeElements.add(n);
}
updateElement(e, t) {
if (!e._theme)
return;
t > 0 && t <= 1 && this.setTheme(e._theme);
}
/**
* Set the current theme on the body element
*/
setTheme(e) {
if (this.currentTheme === e)
return;
const t = document.body;
this.currentTheme && t.removeAttribute(`data-theme-${this.currentTheme}`), t.setAttribute(`data-theme-${e}`, ""), this.currentTheme = e, this.scrollyMotion && this.scrollyMotion.emit("themeChange", e);
}
/**
* Get the current active theme
*/
getCurrentTheme() {
return this.currentTheme;
}
/**
* Manually set a theme
*/
setManualTheme(e) {
this.setTheme(e);
}
/**
* Clear the current theme
*/
clearTheme() {
this.currentTheme && (document.body.removeAttribute(`data-theme-${this.currentTheme}`), this.currentTheme = null, this.scrollyMotion && this.scrollyMotion.emit("themeChange", null));
}
/**
* Get all elements with theme configuration
*/
getThemeElements() {
return Array.from(this.themeElements);
}
/**
* Remove an element from theme tracking
*/
removeElement(e) {
this.themeElements.delete(e);
}
/**
* Update theme based on currently visible elements
* This method can be called to recalculate theme based on all visible elements
*/
updateThemeFromVisibleElements() {
if (!this.scrollyMotion)
return;
const e = this.scrollyMotion.getActiveElements();
for (const t of e)
if (t._theme) {
this.setTheme(t._theme);
return;
}
this.clearTheme();
}
}
const F = () => new ee();
class te {
constructor() {
d(this, "name", "webcomponents");
d(this, "webComponentElements", /* @__PURE__ */ new Map());
}
init(e) {
}
destroy() {
this.webComponentElements.clear();
}
parseElement(e) {
const t = e.getAttribute("data-scroll");
if (!t)
return;
const s = t.match(/wc:\s*([^;]+)/);
if (!s)
return;
const r = s[1].trim(), n = Array.from(
e.querySelectorAll(r)
);
if (n.length === 0)
return;
const o = e;
o._webComponents = r, this.webComponentElements.set(o, n);
}
updateElement(e, t) {
const s = this.webComponentElements.get(e);
!s || s.length === 0 || s.forEach((r) => {
if (typeof r.progress == "function")
try {
r.progress(t);
} catch (n) {
console.warn(
"Error calling progress method on web component:",
n
);
}
});
}
/**
* Handle element enter event
*/
onElementEnter(e) {
const t = this.webComponentElements.get(e);
!t || t.length === 0 || t.forEach((s) => {
if (typeof s.enter == "function")
try {
s.en