@zhsz/cool-design-dv
Version:
258 lines (257 loc) • 7.02 kB
JavaScript
;
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;