UNPKG

@zhsz/cool-design-dv

Version:

258 lines (257 loc) 7.02 kB
"use strict"; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const vue = require("vue"); const util = require("../../utils/util.js"); require("./style.css"); const _hoisted_1 = ["innerHTML"]; const __default__ = vue.defineComponent({ name: "DvMarquee" }); const _sfc_main = /* @__PURE__ */ vue.defineComponent({ ...__default__, props: { // 滚动数据 data: { type: Array, default() { return []; } }, disabled: Boolean, // 滚动方向 direction: { type: String, default: "up", validator(val) { return ["up", "down", "left", "right"].includes(val); } }, // 自动开始 auto: { type: Boolean, default: true }, // 滚动速度,数值越大速度越快 speed: { type: Number, default: 1 }, // 间隔滚动停顿等待时间 waitTime: { type: Number, default: 3e3 }, // 间隔滚动,每次滚动的长度,单位px scrollLength: { type: Number, deault: 0 }, customStyle: { type: Object } }, emits: ["resize"], setup(__props, { emit: __emit }) { const props = __props; const timerId = vue.ref(); const copyHtml = vue.ref(""); const contentWidth = vue.ref(0); const contentHeight = vue.ref(0); const scrollPosition = vue.ref(0); const isPause = vue.ref(false); const content = vue.ref(); const resumeId = vue.ref(); const $emit = __emit; const isHorizontal = vue.computed(() => { return ["left", "right"].includes(props.direction); }); const classes = vue.computed(() => { return { "my-marquee--horizontal": isHorizontal.value, "is-disabled": props.disabled }; }); const scrollStyle = vue.computed(() => { return { transform: isHorizontal.value ? `translate3d(-${scrollPosition.value}px, 0, 0)` : `translate3d(0, -${scrollPosition.value}px, 0)`, width: isHorizontal.value ? `${2 * contentWidth.value}px` : "100%" }; }); function renderCopyHtml() { if (!content.value || props.disabled) return; copyHtml.value = content.value.innerHTML; updateView(); } function updateView() { if (!content.value) return; const rect = content.value.getBoundingClientRect(); contentHeight.value = rect.height; contentWidth.value = rect.width; $emit("resize", rect); } function start() { isPause.value = false; switch (props.direction) { case "up": scrollPosition.value = scrollPosition.value || 0; scrollUp(); break; case "down": scrollPosition.value = scrollPosition.value || contentHeight.value; scrollDown(); break; case "left": scrollPosition.value = scrollPosition.value || 0; scrollLeft(); break; case "right": scrollPosition.value = scrollPosition.value || contentWidth.value; scrollRight(); break; } } function stop() { timerId.value && util.cancelAnimationFrame(timerId.value); resumeId.value && clearTimeout(resumeId.value); } function scrollUp() { timerId.value = util.requestAnimationFrame(() => { if (isPause.value) { return; } scrollPosition.value = scrollPosition.value + props.speed; if (resume()) { isPause.value = true; return; } if (scrollPosition.value >= contentHeight.value) { scrollPosition.value = 0; } scrollUp(); }); } function scrollDown() { timerId.value = util.requestAnimationFrame(() => { if (isPause.value) { return; } scrollPosition.value = scrollPosition.value - props.speed; if (resume()) { isPause.value = true; return; } if (scrollPosition.value <= 0) { scrollPosition.value = contentHeight.value; } scrollDown(); }); } function scrollLeft() { timerId.value = util.requestAnimationFrame(() => { if (isPause.value) { return; } scrollPosition.value = scrollPosition.value + props.speed; if (resume()) { isPause.value = true; return; } if (scrollPosition.value >= contentWidth.value) { scrollPosition.value = 0; } scrollLeft(); }); } function scrollRight() { timerId.value = util.requestAnimationFrame(() => { if (isPause.value) { return; } scrollPosition.value = scrollPosition.value - props.speed; if (resume()) { isPause.value = true; return; } if (scrollPosition.value <= 0) { scrollPosition.value = contentWidth.value; } scrollRight(); }); } function resume() { const value = Math.floor(scrollPosition.value) % ((props == null ? void 0 : props.scrollLength) ?? 0); const match = value === 0; if (match) { resumeId.value && clearTimeout(resumeId.value); resumeId.value = setTimeout(start, props.waitTime); } return match; } function handleMouseEnter() { stop(); isPause.value = true; } function handleMouseLeave() { start(); } vue.watch( () => props.data, () => { vue.nextTick(renderCopyHtml); }, { immediate: true } ); vue.watch( () => props.disabled, (val) => { stop(); if (val) { copyHtml.value = ""; scrollPosition.value = 0; } else { vue.nextTick(renderCopyHtml); props.auto && start(); } } ); vue.onMounted(() => { if (props.auto && !props.disabled) { start(); } }); vue.onBeforeUnmount(() => { stop(); copyHtml.value = ""; }); return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("div", { class: vue.normalizeClass(["my-marquee", classes.value]), style: vue.normalizeStyle(__props.customStyle), onMouseenter: handleMouseEnter, onMouseleave: handleMouseLeave }, [ vue.createElementVNode("div", { class: "my-marquee__scroll", style: vue.normalizeStyle(scrollStyle.value) }, [ vue.createElementVNode("div", { ref_key: "content", ref: content, class: "my-marquee__content" }, [ vue.renderSlot(_ctx.$slots, "default") ], 512), vue.createElementVNode("div", { class: "my-marquee__copy-content", innerHTML: copyHtml.value }, null, 8, _hoisted_1) ], 4) ], 38); }; } }); exports.default = _sfc_main;