UNPKG

@ssgoi/core

Version:

Core animation engine for SSGOI - Native app-like page transitions with spring physics

1,502 lines (1,501 loc) 49 kB
const g = (t, i) => { var r; t.style.position = "absolute", t.style.width = "100%", t.style.top = `${-1 * (((r = i == null ? void 0 : i.scrollOffset) == null ? void 0 : r.y) ?? 0)}px`, t.style.left = "0"; }, _ = (t) => new Promise((i) => setTimeout(i, t)); function x(t, i) { function r(s) { let e = 0, a = 0; const l = s.offsetWidth, y = s.offsetHeight; let o = s; for (; o; ) e += o.offsetTop, a += o.offsetLeft, o = o.offsetParent; return e -= window.scrollY, a -= window.scrollX, { top: e, left: a, width: l, height: y }; } const c = r(t), n = r(i); return new DOMRect( n.left - c.left, n.top - c.top, n.width, n.height ); } function E() { let t, i; return { promise: new Promise((c, n) => { t = c, i = n; }), resolve: t, reject: i }; } const H = { spring: { stiffness: 200, damping: 22 } }, X = { spring: { stiffness: 200, damping: 22 } }, z = 300, W = 10, M = "horizontal", B = "#000000", Mt = (t = {}) => { const { transitionDelay: i = z, blindCount: r = W, direction: c = M, blindColor: n = B } = t, s = t.physics ?? X, e = t.physics ?? H; let a, l = null; const y = (o, h, d = "left") => { window.getComputedStyle(o).position === "static" && (o.style.position = "relative"); const f = document.createElement("div"); f.className = "blind-container", f.style.cssText = ` position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 9999; overflow: hidden; `; const p = []; for (let $ = 0; $ < r; $++) { const w = document.createElement("div"); if (c === "horizontal") { const b = 100 / r, C = `calc(${b}% + 1px)`; w.style.cssText = ` position: absolute; top: ${b * $}%; left: 0; width: 100%; height: ${C}; background: ${n}; transform: scaleX(${h === "hidden" ? 0 : 1}); transform-origin: ${d} center; will-change: transform; `; } else { const b = 100 / r, C = `calc(${b}% + 1px)`; w.style.cssText = ` position: absolute; top: 0; left: ${b * $}%; width: ${C}; height: 100%; background: ${n}; transform: scaleY(${h === "hidden" ? 0 : 1}); transform-origin: ${d === "left" ? "top" : "bottom"} center; will-change: transform; `; } p.push(w), f.appendChild(w); } return o.appendChild(f), { container: f, blinds: p }; }; return { out: (o) => { let h = null; a = new Promise((f) => { l = f; }); const d = (f) => { const p = 1 - f; return { transform: c === "horizontal" ? `scaleX(${p})` : `scaleY(${p})` }; }; return { items: Array.from({ length: r }, (f, p) => ({ physics: e, offset: 0.2, css: { // Use getter for lazy element access (evaluated after prepare) get element() { return h == null ? void 0 : h.blinds[p]; }, style: d } })), schedule: "stagger", prepare: () => { g(o), o.style.zIndex = "1000", h = y(o, "hidden", "left"); }, onStart: () => { }, onEnd: () => { l && l(); } }; }, in: (o) => { let h = null; const d = (f) => { const p = 1 - f; return { transform: c === "horizontal" ? `scaleX(${p})` : `scaleY(${p})` }; }; return { items: Array.from({ length: r }, (f, p) => ({ physics: s, offset: 0.2, css: { // Use getter for lazy element access (evaluated after prepare) get element() { return h == null ? void 0 : h.blinds[p]; }, style: d } })), schedule: "stagger", prepare: () => { o.style.position = "relative", o.style.zIndex = "0", h = y(o, "closed", "right"); }, onStart: () => { }, wait: async () => { a && await a, await _(i); }, onEnd: () => { h && h.container && h.container.remove(); } }; } }; }, q = { spring: { stiffness: 1, damping: 1 } }, j = { spring: { stiffness: 20, damping: 25 } }, N = "#000000", G = "circle", k = "CURTAIN_REVEAL_OVERLAY_ID", Z = { position: "fixed", inset: "0", width: "100vw", height: "100%", zIndex: "9999", display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden" }, J = { position: "relative", display: "inline-block", height: "5.5rem", overflow: "hidden" }, K = { display: "flex", height: "100%", willChange: "transform", transition: "transform 0.3s ease" }, Q = { display: "inline-flex", alignItems: "center", justifyContent: "center", whiteSpace: "nowrap", fontSize: "5.5rem", fontWeight: "900", letterSpacing: "0.02em", color: "#FFFFFF" }, R = 0.4, S = 0.5, tt = 0.2; function st(t, i) { switch (t) { case "circle": return `circle(${i * 100}% at 50% 50%)`; case "square": return `inset(${(1 - i) * 50}% round ${10 * i}%)`; case "triangle": { const r = i * 100; return `polygon(50% ${50 - r}%, ${50 - r}% ${50 + r}%, ${50 + r}% ${50 + r}%)`; } } } const it = (t) => t.reduce((i, r) => i + r, 0), Bt = (t = {}) => { const { background: i = N, texts: r = [], shape: c = G, textStyle: n = {} } = t, s = t.physics ?? j, e = t.physics ?? q; return { out: (a, l) => { const y = a.style.opacity; return { physics: e, from: 1, to: 0, prepare: () => { g(a, l), a.style.opacity = "1"; }, tick: (o) => { const h = Math.max(0, o - R); a.style.opacity = String(h); }, onEnd: () => { a.style.opacity = y; } }; }, in: (a) => { let l = null, y = null, o = null; const h = document.body.style.overflow, d = document.getElementById( k ); let u = []; const f = () => { l = document.createElement("div"), l.id = k, Object.assign(l.style, Z, { background: i }), document.body.appendChild(l), y = document.createElement("div"), Object.assign(y.style, J), l.appendChild(y), o = document.createElement("div"), Object.assign(o.style, K), y.appendChild(o), r.forEach((p) => { const $ = document.createElement("div"); $.textContent = p, Object.assign($.style, Q, n), o.appendChild($); }), u = Array.from(o.children).map( (p) => p.getBoundingClientRect().width ); }; return { physics: s, from: 0, to: 1, prepare: () => { document.body.style.overflow = "hidden", a.style.opacity = "1", d == null || d.remove(), f(), l && y && (l.style.clipPath = "none", y.style.transform = "scale(1)"); }, tick: (p) => { if (!(!l || !y || !o)) { if (p <= S && r.length > 0) { const $ = p / S, w = Math.min( Math.floor($ * r.length), r.length - 1 ), b = u[w] ?? 0, C = it(u.slice(0, w)); y.style.width = `${b}px`, o.style.transform = `translateX(-${C}px)`; } if (p > S) { const w = 1 - Math.max( 0, Math.min(1, (p - S) / tt) ); l.style.clipPath = st(c, w), y.style.transform = `scale(${w})`; } } }, onEnd: () => { l == null || l.remove(), l = y = o = null, document.body.style.overflow = h; } }; } }; }, nt = { spring: { stiffness: 600, damping: 40, restDelta: 0.1, restSpeed: 1e14 } }, et = { spring: { stiffness: 600, damping: 40, restDelta: 0.1, restSpeed: 1e14 } }, at = 0.05; function A(t) { const i = x(document.body, t.positionedParent), r = t.scroll.y, c = window.innerHeight - i.top; return { top: r, left: 0, width: i.width, height: c }; } const qt = (t = {}) => { const { direction: i = "enter" } = t, r = t.physics ?? (i === "enter" ? nt : et), c = t.scaleOffset ?? at; let { promise: n, resolve: s } = E(); return i === "enter" ? { // Entering page: scales up from small (0.8 → 1) with fade in in: (e, a) => { const l = A(a), y = l.left + l.width / 2, o = l.top + l.height / 2; return { physics: r, prepare: () => { e.style.opacity = "0", e.style.willChange = "transform, opacity", e.style.backfaceVisibility = "hidden", e.style.contain = "layout paint", e.style.transformOrigin = `${y}px ${o}px`; }, wait: async () => { if (n) { await n; const h = E(); n = h.promise, s = h.resolve; } }, css: (h) => ({ transform: `scale(${1 - c + h * c})`, opacity: h }), onEnd: () => { e.style.opacity = "1", e.style.willChange = "auto", e.style.backfaceVisibility = "", e.style.contain = "", e.style.transformOrigin = ""; } }; }, // Exiting page: scales up (1 → 1.2) with fade out, goes to back out: (e, a) => { const l = A(a), y = l.left + l.width / 2, o = l.top + l.height / 2 + a.scrollOffset.y; return { physics: r, prepare: () => { g(e, a), e.style.zIndex = "-1", e.style.willChange = "transform, opacity", e.style.backfaceVisibility = "hidden", e.style.contain = "layout paint", e.style.pointerEvents = "none", e.style.transformOrigin = `${y}px ${o}px`; }, css: (h) => ({ transform: `scale(${1 + (1 - h) * c})`, opacity: h }), onEnd: () => { s && s(); } }; } } : { // Entering page: scales down from large (1.2 → 1) with fade in in: (e, a) => { const l = A(a), y = l.left + l.width / 2, o = l.top + l.height / 2; return { physics: r, prepare: () => { e.style.opacity = "0", e.style.willChange = "transform, opacity", e.style.backfaceVisibility = "hidden", e.style.contain = "layout paint", e.style.transformOrigin = `${y}px ${o}px`; }, wait: async () => { if (n) { await n; const h = E(); n = h.promise, s = h.resolve; } }, css: (h) => ({ transform: `scale(${1 + c - h * c})`, opacity: h }), onEnd: () => { e.style.opacity = "1", e.style.willChange = "auto", e.style.backfaceVisibility = "", e.style.contain = "", e.style.transformOrigin = ""; } }; }, // Exiting page: scales down to small (1 → 0.8) with fade out out: (e, a) => { const l = A(a), y = l.left + l.width / 2, o = l.top + l.height / 2 + a.scrollOffset.y; return { physics: r, prepare: () => { g(e, a), e.style.zIndex = "100", e.style.willChange = "transform, opacity", e.style.backfaceVisibility = "hidden", e.style.contain = "layout paint", e.style.pointerEvents = "none", e.style.transformOrigin = `${y}px ${o}px`; }, css: (h) => ({ transform: `scale(${1 - (1 - h) * c})`, opacity: h }), onEnd: () => { s && s(); } }; } }; }, rt = { spring: { stiffness: 170, damping: 22 } }, ot = { spring: { stiffness: 170, damping: 22 } }, jt = (t = {}) => { const { opacity: i = !1, direction: r = "enter" } = t, c = t.physics ?? (r === "enter" ? rt : ot); return r === "enter" ? { in: (n) => ({ physics: c, prepare: () => { n.style.willChange = i ? "transform, opacity" : "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint"; }, css: (s) => { const e = { transform: `translate3d(${(1 - s) * 100}%, 0, 0)` }; return i && (e.opacity = s), e; }, onEnd: () => { n.style.willChange = "auto", n.style.backfaceVisibility = "", n.style.contain = ""; } }), out: (n, s) => ({ physics: c, prepare: () => { g(n, s), n.style.zIndex = "-1", n.style.willChange = i ? "transform, opacity" : "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint", n.style.pointerEvents = "none"; }, css: (e) => { const a = { transform: `translate3d(${-(1 - e) * 20}%, 0, 0)` }; return i && (a.opacity = e), a; } }) } : { in: (n) => ({ physics: c, prepare: () => { n.style.willChange = i ? "transform, opacity" : "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint"; }, css: (s) => { const e = { transform: `translate3d(${-(1 - s) * 20}%, 0, 0)` }; return i && (e.opacity = s), e; }, onEnd: () => { n.style.willChange = "auto", n.style.backfaceVisibility = "", n.style.contain = ""; } }), out: (n, s) => ({ physics: c, prepare: () => { g(n, s), n.style.zIndex = "100", n.style.willChange = i ? "transform, opacity" : "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint", n.style.pointerEvents = "none"; }, css: (e) => { const a = { transform: `translate3d(${(1 - e) * 100}%, 0, 0)` }; return i && (a.opacity = e), a; } }) }; }, lt = { spring: { stiffness: 180, damping: 20, doubleSpring: !0 } }, ct = { spring: { stiffness: 170, damping: 20, doubleSpring: !0 } }, yt = 0, Nt = (t = {}) => { const { transitionDelay: i = yt } = t, r = t.physics ?? ct, c = t.physics ?? lt; let { promise: n, resolve: s } = E(); return { in: (e) => ({ physics: r, prepare: () => { e.style.opacity = "0", e.style.willChange = "opacity"; }, wait: async () => { if (n) { await n; const a = E(); n = a.promise, s = a.resolve, await _(i); } }, css: (a) => ({ opacity: a }), onEnd: () => { e.style.willChange = "auto", e.style.opacity = "1"; } }), out: (e, a) => ({ physics: c, css: (l) => ({ opacity: l }), prepare: () => { g(e, a), e.style.willChange = "opacity"; }, onEnd: () => { s && s(), e.style.willChange = "auto"; } }) }; }, ht = { scaleDown: { stiffness: 20, damping: 7 }, // Soft start for cinematic scale translate: { stiffness: 15, damping: 7 }, // Medium for movement scaleUp: { stiffness: 20, damping: 7 } // Crisp return to full size }, O = { scaleDown: 0, // Start immediately translate: 0.2, // Start when scaleDown is 25% complete scaleUp: 0.8 // Start when translate is 70% complete }, pt = 0.8, dt = "white", Gt = (t) => { var n; const i = ht, r = pt, c = ((n = t == null ? void 0 : t.border) == null ? void 0 : n.color) ?? dt; return { out: async (s, e) => { const a = v(e), l = x(document.body, e.positionedParent), y = ft(c, { ...a, top: l.top }), o = { scale: 1, translateY: -a.top }, h = () => { s.style.transform = `translateY(${o.translateY}px) scale(${o.scale})`; const d = (a.width - a.width * o.scale) / 2, u = (a.height - a.height * o.scale) / 2; ut(y, d, u); }; return { items: [ // Spring 1: Scale Down (1 → scale) { physics: (t == null ? void 0 : t.physics) ?? { spring: i.scaleDown }, offset: O.scaleDown, tick: (d) => { const u = 1 - d; o.scale = 1 - (1 - r) * u, h(); } }, // Spring 2: Translate (vertical movement) { physics: (t == null ? void 0 : t.physics) ?? { spring: i.translate }, offset: O.translate, tick: (d) => { const u = 1 - d; o.translateY = -a.top - a.height * u, h(); } }, // Spring 3: Scale Up (scale → 1) { physics: (t == null ? void 0 : t.physics) ?? { spring: i.scaleUp }, offset: O.scaleUp, tick: (d) => { const u = 1 - d; o.scale = r + (1 - r) * u, h(); } } ], schedule: "stagger", prepare: () => { g(s), m(s, a), I(s, a), gt(s, a); for (const d of y) e.positionedParent.appendChild(d); }, onEnd: () => { s.style.clipPath = "", s.style.transformOrigin = "", setTimeout(() => { for (const d of y) e.positionedParent.removeChild(d); }, 1e3); } }; }, in: async (s, e) => { const a = v(e), l = { scale: r, translateY: -a.top + a.height }, y = () => { s.style.transform = `translateY(${l.translateY}px) scale(${l.scale})`; }; return { items: [ // Spring 1: Scale Down (1 → scale) - element starts scaled, shrinks further { physics: (t == null ? void 0 : t.physics) ?? { spring: i.scaleDown }, offset: O.scaleDown, tick: (o) => { l.scale = 1 - (1 - r) * o, y(); } }, // Spring 2: Translate (vertical movement from bottom to top) { physics: (t == null ? void 0 : t.physics) ?? { spring: i.translate }, offset: O.translate, tick: (o) => { l.translateY = -a.top + a.height * (1 - o), y(); } }, // Spring 3: Scale Up (scale → 1) - element returns to full size { physics: (t == null ? void 0 : t.physics) ?? { spring: i.scaleUp }, offset: O.scaleUp, tick: (o) => { l.scale = r + (1 - r) * o, y(); } } ], schedule: "stagger", prepare: () => { m(s, a), I(s, a), s.style.transform = `translateY(${-a.top + a.height}px) scale(${r})`; }, onEnd: () => { s.style.clipPath = "", s.style.transformOrigin = "", s.style.transform = ""; } }; } }; }; function ut(t, i, r) { const c = i * 0.7, n = r * 0.7; t.topLeft.style.transform = `translate(${c}px, ${n}px)`, t.topRight.style.transform = `translate(${-c}px, ${n}px)`, t.bottomLeft.style.transform = `translate(${c}px, ${-n}px)`, t.bottomRight.style.transform = `translate(${-c}px, ${-n}px)`; } function ft(t = "white", i) { const n = document.createElement("div"); n.style.position = "fixed", n.style.pointerEvents = "none", n.style.zIndex = "9999", n.style.top = `${i.top - 1}px`, n.style.left = `${i.left - 1}px`, n.style.width = "15px", n.style.height = "15px"; const s = document.createElement("div"); s.style.position = "absolute", s.style.width = "15px", s.style.height = "1px", s.style.backgroundColor = t, s.style.top = "0", s.style.left = "0"; const e = document.createElement("div"); e.style.position = "absolute", e.style.width = "1px", e.style.height = "15px", e.style.backgroundColor = t, e.style.top = "0", e.style.left = "0", n.appendChild(s), n.appendChild(e); const a = document.createElement("div"); a.style.position = "fixed", a.style.pointerEvents = "none", a.style.zIndex = "9999", a.style.top = `${i.top - 1}px`, a.style.left = `${i.left + i.width - 15 + 1}px`, a.style.width = "15px", a.style.height = "15px"; const l = document.createElement("div"); l.style.position = "absolute", l.style.width = "15px", l.style.height = "1px", l.style.backgroundColor = t, l.style.top = "0", l.style.right = "0"; const y = document.createElement("div"); y.style.position = "absolute", y.style.width = "1px", y.style.height = "15px", y.style.backgroundColor = t, y.style.top = "0", y.style.right = "0", a.appendChild(l), a.appendChild(y); const o = document.createElement("div"); o.style.position = "fixed", o.style.pointerEvents = "none", o.style.zIndex = "9999", o.style.top = `${i.top + i.height - 15 + 1}px`, o.style.left = `${i.left - 1}px`, o.style.width = "15px", o.style.height = "15px"; const h = document.createElement("div"); h.style.position = "absolute", h.style.width = "15px", h.style.height = "1px", h.style.backgroundColor = t, h.style.bottom = "0", h.style.left = "0"; const d = document.createElement("div"); d.style.position = "absolute", d.style.width = "1px", d.style.height = "15px", d.style.backgroundColor = t, d.style.bottom = "0", d.style.left = "0", o.appendChild(h), o.appendChild(d); const u = document.createElement("div"); u.style.position = "fixed", u.style.pointerEvents = "none", u.style.zIndex = "9999", u.style.top = `${i.top + i.height - 15 + 1}px`, u.style.left = `${i.left + i.width - 15 + 1}px`, u.style.width = "15px", u.style.height = "15px"; const f = document.createElement("div"); f.style.position = "absolute", f.style.width = "15px", f.style.height = "1px", f.style.backgroundColor = t, f.style.bottom = "0", f.style.right = "0"; const p = document.createElement("div"); return p.style.position = "absolute", p.style.width = "1px", p.style.height = "15px", p.style.backgroundColor = t, p.style.bottom = "0", p.style.right = "0", u.appendChild(f), u.appendChild(p), { topLeft: n, topRight: a, bottomLeft: o, bottomRight: u, *[Symbol.iterator]() { yield n, yield a, yield o, yield u; } }; } function v(t) { const i = x(document.body, t.positionedParent); return { top: t.scroll.y, left: 0, width: i.width, height: window.innerHeight - i.top }; } function m(t, i) { const r = i.left + i.width / 2, c = i.top + i.height / 2; t.style.transformOrigin = `${r}px ${c}px`; } function I(t, i) { t.style.clipPath = `polygon( ${i.left}px ${i.top}px, ${i.left + i.width}px ${i.top}px, ${i.left + i.width}px ${i.top + i.height}px, ${i.left}px ${i.top + i.height}px )`; } function gt(t, i) { t.style.transform = `translateY(${-i.top}px)`; } const wt = { spring: { stiffness: 300, damping: 30 } }; function $t(t, i) { return t.querySelector(`[data-hero-key="${i}"]`); } const Zt = (t = {}) => { const i = t.physics ?? wt, r = t.maxDistance ?? 700; let c = null, n = E(); return { in: async (s, e) => { const a = s, l = Array.from(a.querySelectorAll("[data-hero-key]")); await n.promise; const y = l.map((o) => { const h = o.getAttribute("data-hero-key"); if (!h) return null; const d = $t(c, h); if (!d) return null; const u = o, f = x(c, d), p = x(a, u), $ = f.left - p.left - e.scrollOffset.x, w = f.top - p.top - e.scrollOffset.y, b = f.width / p.width, C = f.height / p.height, D = u.style.transform, Y = u.style.position, F = u.style.transformOrigin, U = u.style.zIndex, V = u.style.willChange; return { toEl: u, dx: $, dy: w, dw: b, dh: C, originalTransform: D, originalPosition: Y, originalTransformOrigin: F, originalZIndex: U, originalWillChange: V }; }).filter( (o) => o !== null && Math.abs(o.dy) <= r ); return c = null, n = E(), y.length === 0 ? { physics: i, tick: () => { } // No matching hero elements } : { items: y.map(({ toEl: o, dx: h, dy: d, dw: u, dh: f }) => ({ physics: i, tick: (p) => { o.style.transform = `translate(${(1 - p) * h}px, ${(1 - p) * d}px) scale(${p + (1 - p) * u}, ${p + (1 - p) * f})`; } })), schedule: "parallel", prepare: () => { y.forEach(({ toEl: o }) => { o.style.position = "relative", o.style.transformOrigin = "top left", o.style.zIndex = "1000", o.style.willChange = "transform"; }); }, onEnd: () => { y.forEach( ({ toEl: o, originalTransform: h, originalPosition: d, originalTransformOrigin: u, originalZIndex: f, originalWillChange: p }) => { o.style.transform = h, o.style.position = d, o.style.transformOrigin = u, o.style.zIndex = f, o.style.willChange = p; } ); } }; }, out: async (s) => ({ physics: i, tick: () => { }, prepare: () => { c = s, n.resolve(), g(s), s.style.opacity = "0"; } }) }; }, bt = { spring: { stiffness: 180, damping: 22, doubleSpring: 1 } }; function xt({ detailRect: t, galleryRect: i, pageRect: r, scrollOffset: c }) { const n = i.left - t.left + (i.width - t.width) / 2 - c.x, s = i.top - t.top + (i.height - t.height) / 2 - c.y, e = i.width / t.width, a = i.height / t.height, l = Math.max(e, a), y = t.top / r.height * 100, o = (r.width - (t.left + t.width)) / r.width * 100, h = (r.height - (t.top + t.height)) / r.height * 100, d = t.left / r.width * 100; return { transformOrigin: `${t.left + t.width / 2}px ${t.top + t.height / 2}px`, animate: (f) => { const p = 1 - f; return { clipPath: `inset(${y * p}% ${o * p}% ${h * p}% ${d * p}%)`, transform: `translate(${n * p}px, ${s * p}px) scale(${1 + (l - 1) * p})` }; } }; } function Et({ detailRect: t, galleryRect: i, pageRect: r, scrollOffset: c }) { const n = i.left - t.left + (i.width - t.width) / 2 + c.x, s = i.top - t.top + (i.height - t.height) / 2 + c.y, e = i.width / t.width, a = i.height / t.height, l = Math.min(e, a), y = t.top / r.height * 100, o = (r.width - (t.left + t.width)) / r.width * 100, h = (r.height - (t.top + t.height)) / r.height * 100, d = t.left / r.width * 100; return { transformOrigin: `${t.left + t.width / 2}px ${t.top + t.height / 2}px`, animate: (f) => { const p = 1 - f; return { clipPath: `inset(${y * p}% ${o * p}% ${h * p}% ${d * p}%)`, transform: `translate(${n * p - c.x}px, ${s * p - c.y}px) scale(${1 + (l - 1) * p})` }; } }; } function Ct(t, i, r) { const c = t.querySelector( "[data-instagram-detail-key]" ), n = i.querySelector( "[data-instagram-detail-key]" ); if (t.querySelectorAll("[data-instagram-detail-key]").length > 1 || i.querySelectorAll("[data-instagram-detail-key]").length > 1) return null; let s = null, e = null, a = !1; if (!c && n) { e = n; const o = e.getAttribute("data-instagram-detail-key"); if (!o) return null; s = t.querySelector( `[data-instagram-gallery-key="${o}"]` ), s && (a = !0); } else if (c && !n) { e = c; const o = e.getAttribute("data-instagram-detail-key"); if (!o) return null; s = i.querySelector( `[data-instagram-gallery-key="${o}"]` ), s && (a = !1); } if (!s || !e) return null; const l = x(a ? t : i, s), y = x(a ? i : t, e); if (a) { const o = xt({ detailRect: y, galleryRect: l, pageRect: i.getBoundingClientRect(), scrollOffset: r }); return i.style.transformOrigin = o.transformOrigin, { isEnterMode: !0, inAnimation: o.animate // No outAnimation - gallery stays visible }; } else { const o = Et({ detailRect: y, galleryRect: l, pageRect: t.getBoundingClientRect(), scrollOffset: r }); return t.style.transformOrigin = o.transformOrigin, { isEnterMode: !1, outAnimation: o.animate // No inAnimation - gallery stays visible }; } } const Jt = (t = {}) => { const i = t.physics ?? bt, r = t.timeout ?? 300; let c = null, n = null, s = null, e = null; return { in: async (a, { scrollOffset: l }) => { const y = a; return !await new Promise((h) => { c ? h(!0) : (n = h, setTimeout(() => { n = null, h(!1); }, r)); }) || !c ? (e == null || e(), e = null, c = null, { physics: i, css: () => ({}) }) : (s = Ct(c, y, l), e == null || e(), e = null, s ? (c = null, { physics: i, css: (h) => s != null && s.inAnimation ? s.inAnimation(h) : {} }) : (c = null, { physics: i, css: () => ({}) })); }, out: async (a, l) => { const y = new Promise((o) => { e = o; }); return { physics: i, prepare: () => { s != null && s.isEnterMode ? g(a) : (g(a, l), a.style.zIndex = "-1"); }, wait: async () => { c = a, n && (n(!0), n = null), await y; }, css: (o) => s != null && s.outAnimation ? s.outAnimation(o) : {} }; } }; }, Ot = { spring: { stiffness: 50, damping: 30 } }; function St(t) { const i = x(document.body, t.positionedParent); return { top: t.scroll.y, left: 0, width: i.width, height: window.innerHeight - i.top }; } const Kt = (t = {}) => { const i = t.physics ?? Ot, r = t.initialRotation ?? 45, c = t.initialScale ?? 0.01, n = t.rotationTriggerPoint ?? 0.8; return { out: async (s, e) => { const a = s.style.opacity; return { physics: { spring: { stiffness: 80, damping: 25 } }, from: 1, to: 0, prepare: () => { g(s, e), s.style.opacity = "1"; }, tick: (l) => { s.style.opacity = String(l); }, onEnd: () => { s.style.opacity = a; } }; }, in: async (s, e) => { const a = St(e), l = s.style.transform, y = s.style.transformOrigin, o = s.style.position, h = s.style.zIndex; return { physics: i, from: 0, to: 1, prepare: () => { const d = Math.min(a.width, a.height) * 0.4; s.style.setProperty( "--max-border-radius", `${d}px` ), s.style.setProperty("--border-radius-scale", "1"), s.style.willChange = "transform", s.style.backfaceVisibility = "hidden"; const u = a.left + a.width / 2, f = a.top + a.height / 2; s.style.transformOrigin = `${u}px ${f}px`, s.style.position = "fixed", s.style.top = `${a.top}px`, s.style.left = `${a.left}px`, s.style.width = `${a.width}px`, s.style.height = `${a.height}px`, s.style.zIndex = "1000", s.style.overflow = "hidden", s.style.transform = `rotate(${r}deg) scale(${c}) translateZ(0)`, s.style.borderRadius = "calc(var(--max-border-radius) * var(--border-radius-scale))", s.style.opacity = "1"; }, tick: (d) => { let u; if (d <= 0.05) u = c; else if (d <= n) { const w = (d - 0.05) / (n - 0.05), b = Math.pow(w, 9); u = c + (0.8 - c) * b; } else { const w = (d - n) / (1 - n); u = 0.8 + 0.2 * (1 - Math.pow(1 - w, 3)); } let f; const p = 0.7; if (d <= p) f = r; else { const w = (d - p) / (1 - p), b = 1 - Math.pow(1 - w, 2); f = r * (1 - b); } let $; if (d <= p) $ = 1; else { const w = (d - p) / (1 - p); $ = 1 - Math.pow(w, 0.5); } s.style.transform = `rotate(${f.toFixed(2)}deg) scale(${u.toFixed(4)}) translateZ(0)`, s.style.setProperty( "--border-radius-scale", $.toFixed(4) ); }, onEnd: () => { s.style.willChange = "", s.style.backfaceVisibility = "", s.style.removeProperty("--max-border-radius"), s.style.removeProperty("--border-radius-scale"), s.style.transform = l, s.style.transformOrigin = y, s.style.position = o, s.style.zIndex = h, s.style.top = "", s.style.left = "", s.style.width = "", s.style.height = "", s.style.overflow = "", s.style.borderRadius = ""; } }; } }; }, At = { spring: { stiffness: 200, damping: 23, doubleSpring: 1 } }; function Tt({ detailRect: t, galleryRect: i, pageRect: r, scrollOffset: c }) { const n = i.left - t.left + (i.width - t.width) / 2 - c.x, s = i.top - t.top + (i.height - t.height) / 2 - c.y, e = i.width / t.width, a = i.height / t.height, l = Math.max(e, a), y = t.top / r.height * 100, o = (r.width - (t.left + t.width)) / r.width * 100, h = (r.height - (t.top + t.height)) / r.height * 100, d = t.left / r.width * 100; return { transformOrigin: `${t.left + t.width / 2}px ${t.top + t.height / 2}px`, animate: (f) => { const p = 1 - f; return { clipPath: `inset(${y * p}% ${o * p}% ${h * p}% ${d * p}%)`, transform: `translate(${n * p}px, ${s * p}px) scale(${1 + (l - 1) * p})` }; } }; } function Lt({ galleryRect: t, detailRect: i, scrollOffset: r }) { const c = i.left - t.left + (i.width - t.width) / 2 + r.x, n = i.top - t.top + (i.height - t.height) / 2 + r.y, s = i.width / t.width, e = i.height / t.height, a = Math.max(s, e); return { transformOrigin: `${t.left + t.width / 2}px ${t.top + t.height / 2}px`, animate: (y) => { const o = 1 - y; return { transform: `translate(${c * o - r.x}px, ${n * o - r.y}px) scale(${1 + (a - 1) * o})`, opacity: `${1 - o}` }; } }; } function Pt({ galleryRect: t, detailRect: i, scrollOffset: r }) { const c = i.left - t.left + (i.width - t.width) / 2 - r.x, n = i.top - t.top + (i.height - t.height) / 2 - r.y, s = i.width / t.width, e = i.height / t.height, a = Math.max(s, e); return { transformOrigin: `${t.left + t.width / 2}px ${t.top + t.height / 2}px`, animate: (y) => { const o = 1 - y, h = y; return { transform: `translate(${c * o}px, ${n * o}px) scale(${1 + (a - 1) * o})`, opacity: `${h}` }; } }; } function kt({ detailRect: t, galleryRect: i, pageRect: r, scrollOffset: c }) { const n = i.left - t.left + (i.width - t.width) / 2 + c.x, s = i.top - t.top + (i.height - t.height) / 2 + c.y, e = i.width / t.width, a = i.height / t.height, l = Math.min(e, a), y = t.top / r.height * 100, o = (r.width - (t.left + t.width)) / r.width * 100, h = (r.height - (t.top + t.height)) / r.height * 100, d = t.left / r.width * 100; return { transformOrigin: `${t.left + t.width / 2}px ${t.top + t.height / 2}px`, animate: (f) => { const p = 1 - f; return { clipPath: `inset(${y * p}% ${o * p}% ${h * p}% ${d * p}%)`, transform: `translate(${n * p - c.x}px, ${s * p - c.y}px) scale(${1 + (l - 1) * p})` }; } }; } function vt(t, i, r) { const c = t.querySelector( "[data-pinterest-detail-key]" ), n = i.querySelector( "[data-pinterest-detail-key]" ); if (t.querySelectorAll("[data-pinterest-detail-key]").length > 1 || i.querySelectorAll("[data-pinterest-detail-key]").length > 1) return null; let s = null, e = null, a = !1; if (!c && n) { e = n; const o = e.getAttribute("data-pinterest-detail-key"); if (!o) return null; s = t.querySelector( `[data-pinterest-gallery-key="${o}"]` ), s && (a = !0); } else if (c && !n) { e = c; const o = e.getAttribute("data-pinterest-detail-key"); if (!o) return null; s = i.querySelector( `[data-pinterest-gallery-key="${o}"]` ), s && (a = !1); } if (!s || !e) return null; const l = x(a ? t : i, s), y = x(a ? i : t, e); if (a) { const o = Tt({ detailRect: y, galleryRect: l, pageRect: i.getBoundingClientRect(), scrollOffset: r }), h = Lt({ galleryRect: l, detailRect: y, scrollOffset: r }); return i.style.transformOrigin = o.transformOrigin, t.style.transformOrigin = h.transformOrigin, { inAnimation: o.animate, outAnimation: h.animate }; } else { const o = Pt({ galleryRect: l, detailRect: y, scrollOffset: r }), h = kt({ detailRect: y, galleryRect: l, pageRect: t.getBoundingClientRect(), scrollOffset: r }); return i.style.transformOrigin = o.transformOrigin, t.style.transformOrigin = h.transformOrigin, { inAnimation: o.animate, outAnimation: h.animate }; } } const Qt = (t = {}) => { const i = t.physics ?? At, r = t.timeout ?? 300; let c = null, n = null, s = null, e = null; return { in: async (a, { scrollOffset: l }) => { const y = a; return !await new Promise((h) => { c ? h(!0) : (n = h, setTimeout(() => { n = null, h(!1); }, r)); }) || !c ? (e == null || e(), e = null, c = null, { physics: i, css: () => ({}) }) : (s = vt(c, y, l), e == null || e(), e = null, s ? (c = null, { physics: i, css: (h) => s ? s.inAnimation(h) : {} }) : (c = null, { physics: i, css: () => ({}) })); }, out: async (a) => { const l = new Promise((y) => { e = y; }); return { physics: i, prepare: () => { g(a), a.style.zIndex = "-1", c = a, n && (n(!0), n = null); }, wait: async () => { await l; }, css: (y) => s ? s.outAnimation(y) : {} }; } }; }, mt = { spring: { stiffness: 100, damping: 30 } }, Rt = (t = {}) => { const i = t.physics ?? mt; return { in: (r) => ({ physics: i, prepare: () => { r.style.opacity = "0", r.style.transform = "rotate(-180deg)", r.style.transformOrigin = "center center", r.style.willChange = "transform, opacity"; }, css: (c) => ({ // -180deg → 0deg, show after 90deg (progress > 0.5) transform: `rotate(${(c - 1) * 180}deg)`, opacity: c > 0.5 ? 1 : 0 }), onEnd: () => { r.style.willChange = "auto", r.style.transform = "", r.style.transformOrigin = "", r.style.opacity = ""; } }), out: (r, c) => ({ physics: i, prepare: () => { g(r, c), r.style.transformOrigin = "center center", r.style.willChange = "transform, opacity"; }, css: (n) => ({ // 0deg → 180deg, hide after 90deg (progress < 0.5) transform: `rotate(${(1 - n) * 180}deg)`, opacity: n > 0.5 ? 1 : 0 }), onEnd: () => { r.style.willChange = "auto"; } }) }; }, It = { spring: { stiffness: 5, damping: 4 } }, ts = (t = {}) => { const i = t.direction ?? "up", r = t.physics ?? It, c = i === "up"; let n = null, s = null, e = null; const a = () => { if (n === null || s === null) return null; const l = Math.min(n, s), y = window.innerHeight; return Math.max(l, y); }; return { in: (l) => (s = l.offsetHeight, n !== null && (e = a()), { physics: r, prepare: () => { l.style.willChange = "transform", l.style.backfaceVisibility = "hidden", l.style.contain = "layout paint"; }, tick: (y) => { e === null && (e = a()); const o = e ?? window.innerHeight, h = c ? (1 - y) * o : (1 - y) * -o; l.style.transform = `translate3d(0, ${h}px, 0)`; }, onEnd: () => { l.style.willChange = "auto", l.style.backfaceVisibility = "", l.style.contain = ""; } }), out: (l, y) => ({ physics: r, tick: (o) => { e === null && (e = a()); const h = e ?? window.innerHeight, d = c ? (1 - o) * -h : (1 - o) * h; l.style.transform = `translate3d(0, ${d}px, 0)`; }, prepare: () => { n = l.offsetHeight, s !== null && (e = a()), g(l, y), l.style.zIndex = c ? "-1" : "1", l.style.willChange = "transform", l.style.backfaceVisibility = "hidden", l.style.contain = "layout paint", l.style.pointerEvents = "none"; } }) }; }, _t = { inertia: { acceleration: 20, resistance: 1.5 } }, Dt = { inertia: { acceleration: 20, resistance: 1 } }, Yt = 0.2; function T(t) { const i = x(document.body, t.positionedParent), r = t.scroll.y, c = window.innerHeight - i.top; return { top: r, left: 0, width: i.width, height: c }; } const ss = (t = {}) => { const { direction: i = "enter" } = t, r = t.physics ?? (i === "enter" ? _t : Dt), c = t.scaleOffset ?? Yt; return i === "enter" ? { // Entering sheet: slides up from bottom in: (n, s) => { const a = T(s).height; return { physics: r, prepare: () => { n.style.willChange = "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint"; }, css: (l) => ({ transform: `translate3d(0, ${(1 - l) * a}px, 0)` }), onEnd: () => { n.style.willChange = "auto", n.style.backfaceVisibility = "", n.style.contain = ""; } }; }, // Exiting background: scales down with fade out: (n, s) => { const e = T(s), a = e.left + e.width / 2, l = e.top + e.height / 2 + s.scrollOffset.y; return { physics: r, prepare: () => { g(n, s), n.style.zIndex = "-1", n.style.willChange = "transform, opacity", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint", n.style.pointerEvents = "none", n.style.transformOrigin = `${a}px ${l}px`; }, css: (y) => ({ transform: `scale(${1 - c + y * c})`, opacity: y }) }; } } : { // Entering background: scales up with fade in: (n, s) => { const e = T(s), a = e.left + e.width / 2, l = e.top + e.height / 2; return { physics: r, prepare: () => { n.style.willChange = "transform, opacity", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint", n.style.transformOrigin = `${a}px ${l}px`; }, css: (y) => ({ transform: `scale(${1 - c + y * c})`, opacity: y }), onEnd: () => { n.style.willChange = "auto", n.style.backfaceVisibility = "", n.style.contain = "", n.style.transformOrigin = ""; } }; }, // Exiting sheet: slides down with high z-index out: (n, s) => { const a = T(s).height; return { physics: r, prepare: () => { g(n, s), n.style.zIndex = "100", n.style.willChange = "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint", n.style.pointerEvents = "none"; }, css: (l) => ({ transform: `translate3d(0, ${(1 - l) * a}px, 0)` }) }; } }; }, Ft = { spring: { stiffness: 140, damping: 19, doubleSpring: 0.8 } }, is = (t = {}) => { const i = t.direction ?? "left", r = t.physics ?? Ft, c = i === "left"; return { in: (n) => ({ physics: r, prepare: () => { n.style.willChange = "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint"; }, css: (s) => ({ transform: `translate3d(${c ? (1 - s) * 100 : (1 - s) * -100}%, 0, 0)` }), onEnd: () => { n.style.willChange = "auto", n.style.backfaceVisibility = "", n.style.contain = ""; } }), out: (n, s) => ({ physics: r, css: (e) => ({ transform: `translate3d(${c ? (1 - e) * -100 : (1 - e) * 100}%, 0, 0)` }), prepare: () => { g(n, s), n.style.willChange = "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint", n.style.pointerEvents = "none"; } }) }; }, Ut = 8, Vt = { spring: { stiffness: 600, damping: 40, restDelta: 0.1, restSpeed: 1e14 } }, ns = (t = {}) => { const i = t.direction ?? "left", r = t.physics ?? Vt, c = t.translateOffset ?? Ut, n = i === "left"; let { promise: s, resolve: e } = E(); return { // Entering page: fades in + slides from opposite direction in: (a) => ({ physics: r, prepare: () => { a.style.opacity = "0", a.style.willChange = "transform, opacity", a.style.backfaceVisibility = "hidden", a.style.contain = "layout paint"; }, wait: async () => { if (s) { await s; const l = E(); s = l.promise, e = l.resolve; } }, css: (l) => { const y = n ? (1 - l) * c : (1 - l) * -c, o = `${l}`; return { transform: `translate3d(${y}px, 0, 0)`, opacity: o }; }, onEnd: () => { a.style.opacity = "1", a.style.willChange = "auto", a.style.backfaceVisibility = "", a.style.contain = ""; } }), // Exiting page: fade out + slide in same direction as navigation out: (a, l) => ({ physics: r, prepare: () => { g(a, l), a.style.willChange = "transform, opacity", a.style.backfaceVisibility = "hidden", a.style.contain = "layout paint", a.style.pointerEvents = "none"; }, css: (y) => { const o = n ? (1 - y) * -c : (1 - y) * c, h = `${y}`; return { transform: `translate3d(${o}px, 0, 0)`, opacity: h }; }, onEnd: () => { e && e(), a.style.willChange = "auto", a.style.backfaceVisibility = "", a.style.contain = ""; } }) }; }, Ht = { spring: { stiffness: 17, damping: 6 } }, P = 20, L = 800, es = (t = {}) => { const i = t.physics ?? Ht; let r, c = null; return { in: (n) => ({ physics: i, prepare: () => { n.style.willChange = "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint", n.style.transform = `perspective(${L}px) rotateY(${P}deg) translate3d(-100%, 0, 0)`; }, wait: async () => { r && await r; }, css: (s) => { const e = (1 - s) * P, a = -(1 - s) * 100; return { transform: `perspective(${L}px) rotateY(${e}deg) translate3d(${a}%, 0, 0)` }; }, onEnd: () => { n.style.transform = "", n.style.willChange = "auto", n.style.backfaceVisibility = "", n.style.contain = ""; } }), out: (n, s) => (r = new Promise((e) => { c = e; }), { physics: i, prepare: () => { g(n, s), n.style.willChange = "transform", n.style.backfaceVisibility = "hidden", n.style.contain = "layout paint", n.style.pointerEvents = "none", n.style.transform = `perspective(${L}px) rotateY(0deg) translate3d(0%, 0, 0)`; }, css: (e) => { const a = 1 - e, l = a * P, y = a * 100; return { transform: `perspective(${L}px) rotateY(${-l}deg) translate3d(${y}%, 0, 0)` }; }, onEnd: () => { c && c(), n.style.transform = ""; } }) }; }, Xt = { spring: { stiffness: 600, damping: 40, restDelta: 0.1, restSpeed: 1e14 } }, zt = 0.05; function Wt(t) { const i = x(document.body, t.positionedParent), r = t.scroll.y, c = window.innerHeight - i.top; return { top: r, left: 0, width: i.width, height: c }; } const as = (t = {}) => { const i = t.physics ?? Xt, r = t.scaleOffset ?? zt; let { promise: c, resolve: n } = E(); return { // Entering page: scales up from small (0.95 → 1) with fade in in: (s, e) => { const a = Wt(e), l = a.left + a.width / 2, y = a.top + a.height / 2; return { physics: i, prepare: () => { s.style.opacity = "0", s.style.willChange = "transform, opacity", s.style.backfaceVisibility = "hidden", s.style.contain = "layout paint", s.style.transformOrigin = `${l}px ${y}px`; }, wait: async () => { if (c) { await c; const o = E(); c = o.promise, n = o.resolve; } }, css: (o) => ({ transform: `scale(${1 - r + o * r})`, opacity: o }), onEnd: () => { s.style.opacity = "1", s.style.willChange = "auto", s.style.backfaceVisibility = "", s.style.contain = "", s.style.transformOrigin = ""; } }; }, // Exiting page: fade out only (no scale) out: (s, e) => ({ physics: i, prepare: () => { g(s, e), s.style.willChange = "opacity", s.style.backfaceVisibility = "hidden", s.style.contain = "layout paint", s.style.pointerEvents = "none"; }, css: (a) => ({ opacity: a }), onEnd: () => { n && n(); } }) }; }; export { Mt as blind, Bt as curtainReveal, qt as depth, jt as drill, Nt as fade, Gt as film, Zt as hero, Jt as instagram, Kt as jaemin, Qt as pinterest, Rt as rotate, ts as scroll, ss as sheet, is as slide, ns as snap, es as strip, as as swap };