import { defineComponent, onMounted, reactive, ref, watch } from 'vue'; import styles from './index.module.less'; export default defineComponent({ name: 'TheNoticeBar', props: { text: { type: String, default: '' }, isAnimation: { type: Boolean, default: false } }, setup(props) { const wrapRef = ref(); const contentRef = ref(); const notiData = reactive({ isActive: false, wrapWidth: 0, contentWidth: 0, contentStyle: { transitionDuration: '0s', transform: 'translateX(0px)' }, time: null as any }); const init = () => { if (notiData.isActive || !contentRef.value || !wrapRef.value) return; notiData.isActive = true; notiData.contentWidth = contentRef.value.getBoundingClientRect().width; notiData.wrapWidth = wrapRef.value.getBoundingClientRect().width; startAnimate(); }; const startAnimate = () => { if (notiData.contentWidth <= notiData.wrapWidth || !notiData.isActive) { notiData.contentStyle.transitionDuration = '0s'; notiData.contentStyle.transform = 'translateX(0px)'; return; } notiData.contentStyle.transitionDuration = '5s'; notiData.contentStyle.transform = 'translateX(-100%)'; notiData.time = setTimeout(() => { notiData.contentStyle.transitionDuration = '0s'; notiData.contentStyle.transform = `translateX(${notiData.wrapWidth}px)`; requestAnimationFrame(() => { requestAnimationFrame(() => { startAnimate(); }) }); }, 5 * 1000); }; const stopAnimate = () => { clearTimeout(notiData.time); notiData.isActive = false; notiData.contentStyle.transitionDuration = '0s'; notiData.contentStyle.transform = 'translateX(0px)'; notiData.time = null; }; watch(() => props.isAnimation, (val) => { if (val) { init(); } else { stopAnimate(); } }) return () => (
init()} onMouseleave={() => stopAnimate()}>
{props.text}
); } });