motion-plus-vue
Version:
Motion Plus Vue
185 lines (184 loc) • 6.47 kB
JavaScript
import { defineComponent as oe, reactive as se, ref as re, computed as s, useSlots as le, watch as ue, createVNode as H, toRef as ce, createBlock as z, openBlock as p, unref as r, mergeProps as de, withCtx as O, normalizeStyle as fe, createElementBlock as _, Fragment as M, renderList as V, resolveDynamicComponent as K, isVNode as pe } from "vue";
import { useMotionValue as y, useTransform as me, wrap as ge, useDomRef as W, useInView as Se, useReducedMotion as ve, resize as ze, useAnimationFrame as ye, motion as G, animate as J } from "motion-v";
import Q from "./TickerItem.vue.mjs";
import { useKeyboardFocus as xe } from "./use-keyboard-focus.mjs";
import { defaultBounds as U } from "./const.mjs";
import { flattenSlots as Pe, renderVNode as X } from "../../utils/flatten-slots.mjs";
function he(m) {
return typeof m == "function" || Object.prototype.toString.call(m) === "[object Object]" && !pe(m);
}
const Be = /* @__PURE__ */ oe({
__name: "Ticker",
props: {
axis: {
default: "x"
},
style: {},
velocity: {
default: 50
},
hoverFactor: {
default: 1
},
gap: {
default: 10
},
align: {
default: "center"
},
offset: {}
},
setup(m) {
const i = m, e = se({
listSize: 0,
containerSize: 0,
containerPaddingStart: 0,
containerPaddingEnd: 0,
itemSizes: []
}), x = re(!1), P = y(1), E = y(0), g = s(() => i.offset ?? E), h = y(0);
me(() => (h.set(ge(-e.listSize - i.gap - e.containerPaddingStart, -e.containerPaddingStart, g.value.get())), h.get()));
const k = y(0), v = s(() => x.value ? k : h), Y = s(() => i.align === "start" ? "flex-start" : i.align === "center" ? "center" : "flex-end"), l = W(), w = W(), C = Se(l, {
margin: "100px"
}), Z = ve();
function $() {
if (!l.value || !w.value) return;
const {
axis: n
} = i, t = n === "x" ? "offsetWidth" : "offsetHeight", a = n === "x" ? "offsetLeft" : "offsetTop", o = n === "x" ? "paddingLeft" : "paddingTop", d = n === "x" ? "paddingRight" : "paddingBottom", u = l.value, S = w.value.querySelectorAll(".ticker-item");
if (!S.length) return;
let D = !1;
const f = [];
for (let c = 0; c < S.length; c++) {
const F = S[c];
f.push({
start: F[a],
end: F[a] + F[t]
}), (!e.itemSizes[c] || f[c].start !== e.itemSizes[c].start || f[c].end !== e.itemSizes[c].end) && (D = !0);
}
const N = u[t], A = f[f.length - 1].end - f[0].start, q = window.getComputedStyle(u), ie = parseInt(q[o] ?? 0), ae = parseInt(q[d] ?? 0);
(A !== e.listSize || N !== e.containerSize || D) && (e.listSize = A, e.containerSize = N, e.containerPaddingStart = ie, e.containerPaddingEnd = ae, e.itemSizes = f);
}
const I = le(), R = s(() => {
var n;
return Pe((n = I.default) == null ? void 0 : n.call(I));
});
ue([R, C, l], (n, t, a) => {
if (!C.value || !l.value) return;
$();
const o = ze(l.value, $);
a(o);
}, {
immediate: !0,
flush: "sync"
});
const b = s(() => e.containerSize > 0 && e.listSize > 0);
ye((n, t) => {
if (b.value && C.value && g.value === E && !Z.value) {
const a = t / 1e3 * (i.velocity * P.get());
g.value.set(g.value.get() - a);
}
});
const T = s(() => {
let n = 0;
if (!b.value || !e.containerSize) return 0;
let t = 0;
const a = Math.max(...e.itemSizes.map((o) => o.end - o.start));
for (; t < e.containerSize + e.containerPaddingStart; )
t = (e.listSize + i.gap) * (n + 1) - a, n++;
return Math.max(n - 1, 0);
}), j = s(() => e.listSize === 0 ? 0 : (e.listSize + i.gap) * (T.value + 1)), ee = s(() => {
const n = [];
for (let t = 0; t < T.value; t++)
R.value.forEach((a, o) => {
let d;
const u = e.itemSizes[o], B = (e.listSize + i.gap) * (t + 1), S = u ? {
start: u.start + B,
end: u.end + B
} : U;
n.push(H(Q, {
key: `clone-${t}-${o}`,
offset: v.value,
axis: i.axis,
listSize: j.value,
cloneIndex: o,
bounds: S,
containerPaddingStart: e.containerPaddingStart
}, he(d = X([a])) ? d : {
default: () => [d]
}));
});
return n;
}), L = ce(i, "axis");
xe(l, L, k);
const te = {
display: "flex",
position: "relative",
overflow: "hidden"
}, ne = s(() => ({
display: "flex",
position: "relative",
willChange: "transform",
listStyleType: "none",
padding: 0,
margin: 0,
justifyContent: "flex-start",
flexDirection: i.axis === "x" ? "row" : "column",
gap: `${i.gap}px`,
alignItems: Y.value,
x: i.axis === "x" ? v.value : 0,
y: i.axis === "y" ? v.value : 0,
opacity: b.value ? 1 : 0
}));
return (n, t) => (p(), z(r(G).div, de({
...n.$attrs
}, {
ref_key: "containerRef",
ref: l,
"data-size": e.listSize,
style: {
...te,
...i.style
},
onFocusCapture: t[0] || (t[0] = () => {
x.value = !0;
}),
onBlurCapture: t[1] || (t[1] = () => {
x.value = !1, g.value.set(r(k).get());
}),
onPointerenter: t[2] || (t[2] = () => {
r(J)(r(P), n.hoverFactor);
}),
onPointerleave: t[3] || (t[3] = () => {
r(J)(r(P), 1);
})
}), {
default: O(() => [H(r(G).ul, {
ref_key: "listRef",
ref: w,
style: fe(ne.value)
}, {
default: O(() => [(p(!0), _(M, null, V(R.value, (a, o) => (p(), z(Q, {
key: `original-${o}`,
axis: L.value,
offset: v.value,
"list-size": j.value,
"item-index": o,
bounds: e.itemSizes[o] ?? r(U),
"container-padding-start": e.containerPaddingStart
}, {
default: O(() => [(p(!0), _(M, null, V(r(X)([a]), (d, u) => (p(), z(K(d), {
key: u
}))), 128))]),
_: 2
}, 1032, ["axis", "offset", "list-size", "item-index", "bounds", "container-padding-start"]))), 128)), (p(!0), _(M, null, V(ee.value, (a) => (p(), z(K(a), {
key: a.key
}))), 128))]),
_: 1
}, 8, ["style"])]),
_: 1
}, 16, ["data-size", "style"]));
}
});
export {
Be as default
};