@extclp/vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
232 lines (231 loc) • 7.57 kB
JavaScript
import { defineComponent as te, ref as u, computed as p, createElementBlock as k, openBlock as b, normalizeClass as a, createVNode as _, createElementVNode as c, createBlock as re, createCommentVNode as F, unref as i, withCtx as z, renderSlot as W, Fragment as ne, renderList as ie, normalizeStyle as L, toDisplayString as oe } from "vue";
import "../resize-observer/index.mjs";
import "../slider/index.mjs";
import { useNameHelper as se, useLocale as ae, getStepByWord as le } from "@vexip-ui/config";
import { useSetTimeout as ue, useListener as B } from "@vexip-ui/hooks";
import { throttle as Z, boundRange as D } from "@vexip-ui/utils";
import { formatSeconds as ce } from "./helper.mjs";
import O from "../resize-observer/resize-observer.mjs";
import de from "../slider/slider.vue2.mjs";
const me = ["src"], ke = /* @__PURE__ */ te({
name: "VideoProgress",
__name: "video-progress",
props: {
time: {
type: Number,
default: 0
},
duration: {
type: Number,
default: 0
},
segments: {
type: Array,
default: () => []
},
noPreview: {
type: Boolean,
default: !1
},
previewSrc: {
type: String,
default: ""
}
},
emits: ["change"],
setup(d, { emit: A }) {
const s = d, H = A, o = se("video"), j = ae("video"), { timer: w } = ue(), E = u(0), S = u(!1), P = u(0), R = u(0), T = u(0);
let f = [0, 0], y = 100, x = 60;
const C = u(), $ = u(), g = p(() => {
var e;
return (e = $.value) == null ? void 0 : e.$el;
}), q = u(), h = p(() => {
var e;
return !!((e = $.value) != null && e.sliding[1]);
}), G = p(() => s.duration ? (h.value ? E.value : s.time) / s.duration * 100 : 0), I = p(() => ({
[o.be("progress")]: !0,
[o.bem("progress", "sliding")]: h.value,
[o.bem("progress", "disabled")]: s.duration <= 0
})), J = p(() => {
const e = Math.max(1, s.duration);
let t = s.segments.map((n) => n.time);
t.length || (t = [0, e]), t = t.at(-1) === e ? t : [...t, e], t = t[0] === 0 ? t : [0, ...t];
const r = [];
for (let n = 0, m = t.length - 1; n < m; ++n) {
const l = t[n], v = t[n + 1], V = v - l;
r.push({
start: l,
startPercent: l / e * 100,
end: v,
endPercent: v / e * 100,
duration: V,
durationPercent: V / e * 100,
width: (v - l) / e * 100
});
}
return r;
}), K = p(() => {
var m;
const e = P.value, t = s.segments;
if (!t.length) return "";
let r = -1;
if (e <= 0)
r = 0;
else
for (let l = 1, v = t.length; l < v; ++l)
if (t[l].time > e) {
r = l - 1;
break;
}
r < 0 && (r = t.length - 1);
const n = ((m = t[r]) == null ? void 0 : m.title) || le(j.value.chapterCount, r + 1);
return n && ` (${n})`;
});
B(g, "pointerenter", () => {
clearTimeout(w.hover), w.hover = setTimeout(() => {
S.value = !0;
}, 100);
}), B(g, "pointerleave", () => {
clearTimeout(w.hover), w.hover = setTimeout(() => {
S.value = !1;
}, 100);
}), B(
g,
"pointermove",
Z((e) => {
h.value || N(e);
})
);
function N(e) {
if (!g.value) return;
const t = D(
e.clientX - g.value.getBoundingClientRect().left,
0,
y
);
P.value = t / y * s.duration, R.value = t + f[0], T.value = D(
t - x * 0.5 + f[0],
0,
y - x + f[0] + f[1]
);
}
function Q(e) {
var r, n;
if (!C.value) return;
const t = getComputedStyle(C.value);
f = [parseFloat(t.paddingLeft), parseFloat(t.paddingRight)], y = ((n = (r = e.borderBoxSize) == null ? void 0 : r[0]) == null ? void 0 : n.inlineSize) ?? e.contentRect.width;
}
function U(e) {
var t, r;
x = ((r = (t = e.borderBoxSize) == null ? void 0 : t[0]) == null ? void 0 : r.inlineSize) ?? e.contentRect.width;
}
function Y(e) {
H("change", e / 1e3 * s.duration);
}
const X = Z(N);
function ee() {
E.value = s.time, document.addEventListener("pointermove", X), document.addEventListener("pointerup", M);
}
function M() {
document.removeEventListener("pointermove", X), document.removeEventListener("pointerup", M);
}
return (e, t) => (b(), k("div", {
ref_key: "wrapper",
ref: C,
class: a(I.value)
}, [
_(i(O), { "on-resize": Q }, {
default: z(() => [
_(i(de), {
ref_key: "slider",
ref: $,
class: a(i(o).be("progress-slider")),
value: G.value * 10,
max: 1e3,
vertical: !1,
range: !1,
"hide-tip": "",
"trigger-fade": "",
"flip-marker": "",
disabled: d.duration <= 0,
onChange: Y,
onPointerdown: ee
}, {
filler: z((r) => [
(b(!0), k(ne, null, ie(J.value, (n, m) => (b(), k("div", {
key: m,
class: a(i(o).be("progress-segment")),
style: L({ width: `${n.width}%` })
}, [
c("div", {
class: a(i(o).be("progress-track"))
}, [
c("div", {
class: a(i(o).be("progress-filler")),
style: L({
visibility: r.percent[1] < n.startPercent ? "hidden" : void 0,
transform: `translateX(${Math.min(
Math.max(r.percent[1] - n.startPercent, 0) / n.durationPercent * 100 - 100,
0
)}%) translateZ(0)`
})
}, null, 6)
], 2)
], 6))), 128))
]),
trigger: z(() => [
W(e.$slots, "trigger", {}, () => [
c("div", {
class: a(i(o).be("progress-trigger"))
}, null, 2)
])
]),
_: 3
}, 8, ["class", "value", "disabled"])
]),
_: 3
}),
c("div", {
class: a({
[i(o).be("progress-indicator")]: !0,
[i(o).bem("progress-indicator", "active")]: S.value && !h.value
}),
style: L({ transform: `translateX(${R.value}px) translateZ(0)` })
}, null, 6),
d.noPreview ? F("", !0) : (b(), re(i(O), {
key: 0,
"on-resize": U
}, {
default: z(() => [
c("div", {
ref_key: "preview",
ref: q,
class: a({
[i(o).be("preview")]: !0,
[i(o).bem("preview", "has-image")]: d.previewSrc,
[i(o).bem("preview", "active")]: S.value || h.value
}),
style: L({ transform: `translateX(${T.value}px) translateZ(0)` })
}, [
W(e.$slots, "preview", {}, () => [
d.previewSrc ? (b(), k("div", {
key: 0,
class: a(i(o).be("preview-image"))
}, [
c("img", { src: d.previewSrc }, null, 8, me)
], 2)) : F("", !0),
c("div", {
class: a(i(o).be("preview-time"))
}, oe(i(ce)(P.value) + K.value), 3)
])
], 6)
]),
_: 3
}))
], 2));
}
});
export {
ke as default
};
//# sourceMappingURL=video-progress.vue2.mjs.map