UNPKG

lesca-use-tween

Version:

transition DOM use hooks

345 lines (344 loc) 11.2 kB
import { useEffect as A, Children as B, createElement as K, cloneElement as Z, useState as z, useRef as $ } from "react"; function L(n) { return n && n.__esModule && Object.prototype.hasOwnProperty.call(n, "default") ? n.default : n; } var j, U; function V() { if (U) return j; U = 1; var n = 4, e = 1e-3, t = 1e-7, a = 10, i = 11, o = 1 / (i - 1), h = typeof Float32Array == "function"; function s(r, l) { return 1 - 3 * l + 3 * r; } function u(r, l) { return 3 * l - 6 * r; } function m(r) { return 3 * r; } function c(r, l, f) { return ((s(l, f) * r + u(l, f)) * r + m(l)) * r; } function d(r, l, f) { return 3 * s(l, f) * r * r + 2 * u(l, f) * r + m(l); } function b(r, l, f, F, g) { var y, x, O = 0; do x = l + (f - l) / 2, y = c(x, F, g) - r, y > 0 ? f = x : l = x; while (Math.abs(y) > t && ++O < a); return x; } function S(r, l, f, F) { for (var g = 0; g < n; ++g) { var y = d(l, f, F); if (y === 0) return l; var x = c(l, f, F) - r; l -= x / y; } return l; } function p(r) { return r; } return j = function(r, l, f, F) { if (!(0 <= r && r <= 1 && 0 <= f && f <= 1)) throw new Error("bezier x values must be in [0, 1] range"); if (r === l && f === F) return p; for (var g = h ? new Float32Array(i) : new Array(i), y = 0; y < i; ++y) g[y] = c(y * o, r, f); function x(O) { for (var w = 0, N = 1, k = i - 1; N !== k && g[N] <= O; ++N) w += o; --N; var M = (O - g[N]) / (g[N + 1] - g[N]), v = w + M * o, E = d(v, r, f); return E >= e ? S(O, v, r, f) : E === 0 ? v : b(O, w, w + o, r, f); } return function(O) { return O === 0 ? 0 : O === 1 ? 1 : c(x(O), l, F); }; }, j; } var _ = V(); const q = /* @__PURE__ */ L(_), J = { outQuart: [0.165, 0.84, 0.44, 1] }, C = { from: {}, to: {}, duration: 1e3, delay: 0, easing: J.outQuart, onStart: { is: !1, method: () => { } }, onUpdate: () => { }, onComplete: () => { } }; class P { enable; data; playing; clearNextFrame; playNextFrame; addDataNextFrame; eachResult; result; timestamp; /** * { from, to, duration, delay, easing, onUpdate, onComplete, onStart } * @param {object} options { from, to, duration, delay, easing, onUpdate, onComplete, onStart } * @returns */ constructor(e) { const t = { ...C, ...e }; if (this.enable = !0, this.data = [], this.playing = !1, this.clearNextFrame = !1, this.playNextFrame = !1, this.addDataNextFrame = [], this.timestamp = 0, JSON.stringify(t) !== JSON.stringify(C)) { const a = { method: t.onStart instanceof Function ? t.onStart : t.onStart.method, is: !1 }; Object.keys(t.to).length > 0 && this.data.push({ ...t, onStart: a }); } return this.eachResult = this.result = t.from, this; } add(e) { const t = { ...C, ...e }, { from: a, to: i, duration: o, delay: h, easing: s, onUpdate: u, onComplete: m, onStart: c } = t, d = { from: a, to: i, duration: o, delay: h, easing: s, onUpdate: u, onComplete: m, onStart: c || { method: () => { }, is: !0 } }; return e.onStart ? d.onStart = { method: c instanceof Function ? c : c.method, is: !1 } : d.onStart = { method: () => { }, is: !0 }, this.clearNextFrame && this.addDataNextFrame.push(d), this.data.push(d), this; } clearQueue() { return this.data.length > 0 && (this.clearNextFrame = !0), this.data = [], this.addDataNextFrame = [], this.result = this.eachResult, this.timestamp = (/* @__PURE__ */ new Date()).getTime(), this; } play() { const { requestAnimationFrame: e } = window, [t] = this.data; if (t) { if (this.clearNextFrame) { this.playNextFrame = !0; return; } if (!this.playing) return this.playing = !0, this.enable = !0, this.timestamp = (/* @__PURE__ */ new Date()).getTime(), e(() => this.render()), this; } } stop() { return this.enable = !1, this.playing = !1, this; } render() { const { requestAnimationFrame: e } = window, [t] = this.data; if (!t) return; const { from: a, to: i, duration: o, delay: h, easing: s, onUpdate: u, onComplete: m, onStart: c } = t, d = a || this.result, b = (/* @__PURE__ */ new Date()).getTime() - this.timestamp - (h || 0), [S, p, r, l] = s, f = q(S, p, r, l), F = b / o; if (b < 0) { e(() => this.render()); return; } if (Object.keys(c).length !== 0) if (c instanceof Function) c?.(); else { const { method: y, is: x } = c; !x && y && (c.is = !0, y?.(d)); } let g = {}; Object.entries(i).forEach((y) => { const [x, O] = y, w = Object.entries(d).filter((k) => k[0] === x)[0][1]; if (w === void 0) return; const N = w + (O - w) * f(F); g[x] = N; }), b < o ? (this.eachResult = { ...this.result, ...g }, u?.(this.eachResult), this.enable ? e(() => this.render()) : (this.result = { ...this.result, ...g }, this.clearNextFrame && (this.clearNextFrame = !1, this.addDataNextFrame.length > 0 ? (this.data = [...this.addDataNextFrame], this.addDataNextFrame = []) : this.data = []), this.playNextFrame && (this.playNextFrame = !1, this.play()))) : (this.result = this.eachResult = { ...this.result, ...i }, this.data.shift(), m?.(this.result), this.data.length > 0 ? (this.reset(), this.data[0].from = this.data[0].from || this.result, this.enable && e(() => this.render())) : this.playing = !1); } reset() { this.timestamp = (/* @__PURE__ */ new Date()).getTime(); } } const G = (n) => { let e = 0, t = 0, a = 0; n.length == 4 ? (e = "0x" + n[1] + n[1], t = "0x" + n[2] + n[2], a = "0x" + n[3] + n[3]) : n.length == 7 && (e = "0x" + n[1] + n[2], t = "0x" + n[3] + n[4], a = "0x" + n[5] + n[6]), e /= 255, t /= 255, a /= 255; let i = Math.min(e, t, a), o = Math.max(e, t, a), h = o - i, s = 0, u = 0, m = 0; return h == 0 ? s = 0 : o == e ? s = (t - a) / h % 6 : o == t ? s = (a - e) / h + 2 : s = (e - t) / h + 4, s = Math.round(s * 60), s < 0 && (s += 360), m = (o + i) / 2, u = h == 0 ? 0 : h / (1 - Math.abs(2 * m - 1)), u = +(u * 100).toFixed(1), m = +(m * 100).toFixed(1), [s, u, m]; }, R = ["backgroundColor", "color", "borderColor"], X = [ "scale", "x", "y", "rotate", "rotateY", "rotateX", "rotateZ", "skewX", "skewY" ], Y = { scale: "scale", rotate: "rotate", x: "translateX", y: "translateY", skewX: "skewX", skewY: "skewY", rotateY: "rotateY", rotateX: "rotateX", rotateZ: "rotateZ" }, I = { scale: "", rotate: "deg", x: "px", y: "px", skewX: "deg", skewY: "deg", rotateY: "deg", rotateX: "deg", rotateZ: "deg" }, W = (n) => { const e = G(n), [t, a, i] = e; return [{ h: t, s: a, l: i }, "hsl"]; }, H = (n) => { const e = String(n), t = parseFloat(e), a = e.split(String(t)).join(""); return isNaN(t) ? [Number(n), ""] : [t, a]; }, Q = (n, e) => R.filter((a) => a === n).length !== 0 ? W(e) : H(e), tt = (n) => { const e = {}; return Object.entries(n).forEach((t) => { const [a, i] = t, o = X.filter((h) => h === a); if (o.length > 0) { const [h] = o, u = Object.entries(Y).filter((d) => d[0] === h)[0][1], c = Object.entries(I).filter((d) => d[0] === h)[0][1]; e.transform ? e.transform += ` ${u}(${i}${c})` : e.transform = `${u}(${i}${c})`; } else e[a] = i; }), e; }, T = (n, e) => { const t = {}; return Object.entries(n).forEach((a) => { const [i, o] = a, [h, s] = i.split("@"), u = e[h], m = X.filter((c) => c === i); if (u === "hsl") t[h] = { ...t[h], [s]: o }; else if (m.length > 0) { const [c] = m, b = Object.entries(Y).filter((r) => r[0] === c)[0][1], p = Object.entries(I).filter((r) => r[0] === c)[0][1]; t.transform ? t.transform += ` ${b}(${o}${p})` : t.transform = `${b}(${o}${p})`; } else t[h] = `${o}${u}`; }), Object.entries(t).forEach((a) => { const [i, o] = a; if (R.filter((s) => s === i).length !== 0) { const s = o; o instanceof Object && (t[i] = `hsl(${s.h}, ${s.s}%, ${s.l}%)`); } }), t; }, et = { // basic linear: [0, 0, 1, 1], easeIn: [0.42, 0, 1, 1], easeOut: [0, 0, 0.58, 1], easeInOut: [0.42, 0, 0.58, 1], // Sine inSine: [0.47, 0, 0.745, 0.715], outSine: [0.39, 0.575, 0.565, 1], inOutSine: [0.445, 0.05, 0.55, 0.95], // Cubic inCubic: [0.55, 0.055, 0.675, 0.19], outCubic: [0.215, 0.61, 0.355, 1], inOutCubic: [0.645, 0.045, 0.355, 1], // Quint InQuint: [0.755, 0.05, 0.855, 0.06], OutQuint: [0.23, 1, 0.32, 1], InOutQuint: [0.86, 0, 0.07, 1], // Circ inCirc: [0.6, 0.04, 0.98, 0.335], outCirc: [0.075, 0.82, 0.165, 1], inOutCirc: [0.785, 0.135, 0.15, 0.86], // Quad inQuad: [0.55, 0.085, 0.68, 0.53], outQuad: [0.25, 0.46, 0.45, 0.94], inOutQuad: [0.455, 0.03, 0.515, 0.955], // Quart inQuart: [0.895, 0.03, 0.685, 0.22], outQuart: [0.165, 0.84, 0.44, 1], inOutQuart: [0.77, 0, 0.175, 1], // Expo inExpo: [0.95, 0.05, 0.795, 0.035], outExpo: [0.19, 1, 0.22, 1], inOutExpo: [1, 0, 0, 1], // Back inBack: [0.6, -0.28, 0.735, 0.045], outBack: [0.175, 0.885, 0.32, 1.275], inOutBack: [0.68, -0.55, 0.265, 1.55] }, D = { duration: 1e3, easing: et.outQuart, delay: 0, onStart: () => { }, onUpdate: () => { }, onEnd: () => { } }, rt = (n) => { const [e, t] = z(n), a = $({}), i = $({}), o = () => { let s = {}, u = {}; return Object.keys(a.current).length ? (s = a.current, u = i.current) : (Object.entries(e).forEach((m) => { const [c, d] = m, b = Q(c, d); if (b) { const [S, p] = b; p === "hsl" ? Object.entries(S).forEach((r) => { const [l, f] = r; s[`${c}@${l}`] = f; }) : s[c] = S, u[c] = p; } }), i.current = u), { from: s, unit: u }; }, h = $(new P({ from: o().from })); return [ tt(e), (s, u) => { let m; typeof u == "number" ? m = { ...D, duration: u } : m = { ...D, ...u }; const { from: c, unit: d } = o(), b = {}; Object.entries(s).forEach((p) => { const [r, l] = p, f = Q(r, l); if (f) { const [F, g] = f; g === "hsl" ? Object.entries(F).forEach((y) => { const [x, O] = y; b[`${r}@${x}`] = O; }) : b[r] = F; } }), h.current.stop().clearQueue().add({ to: b, from: c, ...m, onUpdate: (p) => { a.current = p, t(T(p, d)), m.onUpdate(p); }, onComplete: (p) => { a.current = p, t(T(p, d)), m.onEnd(p); } }).play(); }, () => { h.current?.stop(); } ]; }, st = ({ children: n, initStyle: e, tweenStyle: t, options: a = { duration: 1e3 } }) => { const [i, o, h] = rt(e); return A(() => (t && o(t, a), () => h()), [t]), B.map(n, (s) => { if (typeof s == "string") return K("div", { style: i, children: s }); const u = s; return Z(u, { ...u.props, style: { ...u.props.style, ...i } }); }); }; export { et as Bezier, st as TweenProvider, P as Tweener, rt as default, rt as useTween };