motion-plus-vue
Version:
Motion Plus Vue
343 lines (342 loc) • 12 kB
JavaScript
import { defineComponent as je, reactive as Re, computed as s, ref as Ve, useSlots as Fe, watch as ge, createVNode as z, toRef as Ne, createElementBlock as B, openBlock as p, Fragment as $, renderSlot as Ae, unref as c, mergeProps as Xe, withCtx as J, normalizeStyle as Ye, renderList as K, createBlock as Q, resolveDynamicComponent as me, isVNode as Ge } from "vue";
import { useMotionValue as P, useTransform as ce, wrap as pe, useDomRef as ve, useInView as We, usePageInView as qe, useReducedMotion as He, resize as he, useAnimationFrame as Je, LayoutGroup as Ke, frame as Qe, animate as v, Motion as Ue, motion as Ze, clamp as et } from "motion-v";
import ye from "./TickerItem.vue.mjs";
import { useFocusNavigation as tt } from "./use-focus-navigation.mjs";
import { defaultPageTransition as nt, defaultFadeTransition as at, alignAlias as ot, defaultBounds as Ie } from "./const.mjs";
import { calcNumClones as it } from "./utils/calc-num-clones.mjs";
import { calcTotalItemLength as st } from "./utils/calc-total-item-length.mjs";
import { flattenSlots as rt, renderVNode as xe } from "../../utils/flatten-slots.mjs";
import { getLayoutStrategy as U } from "./utils/layout-strategy.mjs";
import { provideTicker as lt } from "./context.mjs";
import { findNextItemInset as we } from "../Carousel/utils/find-next-page.mjs";
import { findPrevItemInset as Pe } from "../Carousel/utils/find-prev-page.mjs";
function Le(I) {
return typeof I == "function" || Object.prototype.toString.call(I) === "[object Object]" && !Ge(I);
}
const Pt = /* @__PURE__ */ je({
__name: "Ticker",
props: {
axis: {
default: "x"
},
velocity: {
default: 50
},
hoverFactor: {
default: 1
},
gap: {
default: 10
},
align: {
default: "center"
},
offset: {},
itemSize: {
default: "auto"
},
overflow: {
type: Boolean,
default: !1
},
loop: {
type: Boolean,
default: !0
},
safeMargin: {
default: 0
},
fade: {
default: 0
},
fadeTransition: {
default: () => at
},
pageTransition: {
default: () => nt
},
_dragX: {
type: [Object, Boolean]
},
_dragY: {
type: [Object, Boolean]
},
snap: {
type: [String, Boolean]
},
as: {
default: "div"
},
style: {},
onDragEnd: {},
drag: {
type: [Boolean, String]
},
dragConstraints: {
type: [Boolean, Object]
},
dragMomentum: {
type: Boolean
}
},
setup(I) {
const e = I, t = Re({
direction: "ltr",
visibleLength: 0,
inset: 0,
totalItemLength: 0,
containerLength: 0,
itemPositions: [],
isMeasured: !1,
maxInset: null
}), D = s(() => ot[e.align] || e.align), h = s(() => U(e.axis, t.direction).sign), Z = Ve(!1), E = P(1), ee = P(0), d = s(() => e.offset ?? ee), be = ce(() => t.direction === "rtl" ? pe(t.totalItemLength + e.gap + t.inset, t.inset, d.value.get()) : pe(-t.totalItemLength - e.gap - t.inset, -t.inset, d.value.get())), te = P(0), y = s(() => Z.value ? te : e.loop ? be : d.value), g = ve(), _ = ve(), Se = We(g, {
margin: "100px"
}), Me = qe(), L = s(() => Se.value && Me.value), ke = He(), j = Fe(), x = s(() => {
var n;
return rt((n = j.default) == null ? void 0 : n.call(j));
});
function R() {
if (!g.value || !_.value) return;
const n = window.getComputedStyle(g.value).direction, {
measureItem: i,
lengthProp: a,
viewportLengthProp: o,
getCumulativeInset: u
} = U(e.axis, n), {
safeMargin: l,
overflow: f,
loop: w
} = e, k = r.value === "x" ? "paddingLeft" : "paddingTop", A = r.value === "x" ? "paddingRight" : "paddingBottom", X = g.value, C = _.value.querySelectorAll(".ticker-item");
if (!C.length) return;
let le = !1;
const O = [];
for (let T = 0; T < C.length; T++) {
const q = i(C[T], X);
O.push(q);
const H = t.itemPositions[T];
(!H || q.start !== H.start || q.end !== H.end) && (le = !0);
}
const Y = Math.min(X[a], window[o]);
let G = e.overflow ? window[o] : Y;
l > 0 && (G += l * 2);
const W = st(O), ue = window.getComputedStyle(X), fe = parseInt(ue[k] ?? 0), Ee = parseInt(ue[A] ?? 0), de = f ? u(C[0]) : fe, _e = w === !1 ? Math.max(0, W - Y + fe + Ee) : null;
(G !== t.visibleLength || W !== t.totalItemLength || de !== t.inset || t.itemPositions.length !== O.length || le) && (t.direction = n, t.visibleLength = G, t.itemPositions = O, t.totalItemLength = W, t.inset = de, t.containerLength = Y, t.maxInset = _e, t.isMeasured = !0);
}
ge([x, L, () => e.overflow], (n, i, a) => {
if (!L.value || !g.value) return;
R();
const o = e.overflow ? he(R) : void 0, u = he(g.value, R);
a(() => {
o == null || o(), u();
});
}, {
immediate: !0,
flush: "post"
});
const b = s(() => t.totalItemLength > 0);
Je((n, i) => {
if (b.value && L.value && d.value === ee && !ke.value) {
const a = i / 1e3 * (e.velocity * h.value * E.get());
d.value.set(d.value.get() - a);
}
});
const ne = s(() => !b.value || !t.visibleLength ? 0 : it(t.visibleLength, t.itemPositions, e.gap)), ae = s(() => t.totalItemLength === 0 ? 0 : (t.totalItemLength + e.gap) * (ne.value + 1)), Ce = s(() => {
if (!e.loop) return [];
const n = [];
for (let i = 0; i < ne.value; i++) {
const a = [];
x.value.forEach((u, l) => {
let f;
const w = t.itemPositions[l], k = (t.totalItemLength + e.gap) * (i + 1), A = w ? {
start: w.start + k,
end: w.end + k
} : Ie;
a.push(z(ye, {
key: `clone-${i}-${l}`,
offset: y.value,
axis: e.axis,
listSize: ae.value,
itemIndex: l,
cloneIndex: l,
bounds: A,
alignItems: D.value,
size: e.itemSize,
safeMargin: e.safeMargin,
numItems: x.value.length
}, Le(f = xe([u])) ? f : {
default: () => [f]
}));
});
const o = `ticker-group-${i}`;
n.push(z(Ke, {
key: o,
id: o
}, Le(a) ? a : {
default: () => [a]
}));
}
return n;
}), r = Ne(e, "axis");
tt(g, r, te, d, (n) => {
Z.value = n;
});
const Oe = {
display: "flex",
position: "relative"
}, Te = {
display: "flex",
position: "relative",
willChange: "transform",
listStyleType: "none",
padding: 0,
margin: 0,
justifyContent: "flex-start"
};
function oe(n) {
return t.maxInset !== null ? et(-t.maxInset, 0, n) : n;
}
lt({
state: t,
gap: s(() => e.gap),
clampOffset: oe,
renderedOffset: y
});
const S = s(() => e.axis === "x" ? e == null ? void 0 : e._dragX : e == null ? void 0 : e._dragY);
let M = null;
const V = s(() => t.maxInset !== null ? r.value === "x" ? h.value > 0 ? {
left: t.maxInset * -1,
right: 0
} : {
right: t.maxInset,
left: 0
} : {
top: t.maxInset * -1,
bottom: 0
} : {});
function ie() {
M && (M.stop(), M = null);
}
const ze = s(() => !e.onDragEnd && e.drag && S ? () => {
S.value.jump(d.value.get()), ie();
} : e.onPointerDown), Be = s(() => !e.onDragEnd && e.drag && S.value ? (n, {
velocity: i
}) => {
const a = d.value.get();
ie(), Qe.postRender(() => {
let o = a + i[r.value] * (e.snap ? 0.3 : 0.8);
if (e.snap)
if (i[r.value] < 0)
o = -we(-a, t.itemPositions, e.gap, -o);
else if (i[r.value] > 0)
o = -Pe(-a, t.itemPositions, e.gap, -o, t.containerLength);
else {
const l = -we(-a, t.itemPositions, e.gap, -a), f = -Pe(-a, t.itemPositions, e.gap, -a, t.containerLength);
o = Math.abs(a - l) < Math.abs(a - f) ? l : f;
}
const u = e.loop ? {} : h.value > 0 ? {
max: 0,
min: V.value[r.value === "x" ? "left" : "top"]
} : {
min: 0,
max: V.value.right
};
M = v(S.value, oe(o * h.value) * h.value, e.snap ? e.pageTransition : {
type: "inertia",
velocity: i[r.value],
modifyTarget: () => o,
bounceDamping: 40,
bounceStiffness: 400,
...u
});
});
} : e.onDragEnd), F = P(e.loop ? 0 : 1), N = P(0), $e = s(() => U(r.value, t.direction)), se = s(() => typeof e.fade == "number" ? "px" : ""), re = ce(() => `linear-gradient(to ${$e.value.direction}, rgba(0,0,0,${F.get()}) 0px, black ${e.fade}${se.value}, black calc(100% - ${e.fade}${se.value}), rgba(0,0,0,${N.get()}) 100%)`), De = s(() => e.fade ? {
maskImage: re,
WebkitMaskImage: re
} : {}), m = {
start: !0,
end: !1
};
return ge(y, (n, i, a) => {
const o = (l) => {
if (t.maxInset === null) return;
const f = t.maxInset * -1;
l *= h.value, l < 0 ? m.start && (v(F, 0, e.fadeTransition), m.start = !1) : m.start || (v(F, 1, e.fadeTransition), m.start = !0), l > f ? m.end && (v(N, 0, e.fadeTransition), m.end = !1) : m.end || (v(N, 1, e.fadeTransition), m.end = !0);
};
let u = () => {
};
n && (u = n.on("change", o)), a(u);
}, {
immediate: !0
}), (n, i) => (p(), B($, null, [z(c(Ue), Xe(n.$attrs, {
ref_key: "containerRef",
ref: g,
as: n.as,
style: {
overflowX: !n.overflow && r.value === "x" ? "clip" : void 0,
overflowY: !n.overflow && r.value === "y" ? "clip" : void 0,
...Oe,
...e.style,
...De.value
},
drag: n.drag,
_dragX: n._dragX,
_dragY: n._dragY,
"drag-constraints": V.value,
"drag-momentum": n.dragMomentum,
onPointerenter: i[0] || (i[0] = () => {
c(v)(c(E), n.hoverFactor);
}),
onPointerleave: i[1] || (i[1] = () => {
c(v)(c(E), 1);
}),
onPointerdown: ze.value,
onDragEnd: Be.value
}), {
default: J(() => [z(c(Ze).ul, {
ref_key: "listRef",
ref: _,
role: "group",
style: Ye({
...Te,
flexDirection: r.value === "x" ? "row" : "column",
gap: `${n.gap}px`,
x: r.value === "x" ? y.value : 0,
y: r.value === "y" ? y.value : 0,
opacity: b.value ? 1 : 0,
alignItems: D.value,
willChange: b.value && L.value ? "transform" : void 0,
width: "100%",
height: "100%",
maxHeight: "100%",
maxWidth: "100%"
})
}, {
default: J(() => [(p(!0), B($, null, K(x.value, (a, o) => (p(), Q(ye, {
key: `original-${o}`,
axis: r.value,
offset: y.value,
"list-size": ae.value,
"item-index": o,
bounds: t.itemPositions[o] ?? c(Ie),
"align-items": D.value,
size: n.itemSize,
reproject: n.loop,
"safe-margin": n.safeMargin,
"num-items": x.value.length
}, {
default: J(() => [(p(!0), B($, null, K(c(xe)([a]), (u, l) => (p(), Q(me(u), {
key: l
}))), 128))]),
_: 2
}, 1032, ["axis", "offset", "list-size", "item-index", "bounds", "align-items", "size", "reproject", "safe-margin", "num-items"]))), 128)), (p(!0), B($, null, K(Ce.value, (a) => (p(), Q(me(a), {
key: a.key
}))), 128))]),
_: 1
}, 8, ["style"])]),
_: 1
}, 16, ["as", "style", "drag", "_dragX", "_dragY", "drag-constraints", "drag-momentum", "onPointerdown", "onDragEnd"]), Ae(n.$slots, "after")], 64));
}
});
export {
Pt as default
};