|
@@ -0,0 +1,102 @@
|
|
|
+import { defineComponent, reactive, ref, watch, onMounted } from 'vue';
|
|
|
+import styles from './index.module.less';
|
|
|
+
|
|
|
+const refAnimation = (callback: any) => {
|
|
|
+ requestAnimationFrame(() => {
|
|
|
+ requestAnimationFrame(() => {
|
|
|
+ callback();
|
|
|
+ });
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+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 = () => {
|
|
|
+ console.log('进入准备执行执行init', contentRef.value.getBoundingClientRect().width, wrapRef.value.getBoundingClientRect().width)
|
|
|
+ console.log(!wrapRef.value)
|
|
|
+ if (notiData.isActive || !contentRef.value || !wrapRef.value) return;
|
|
|
+ notiData.isActive = true;
|
|
|
+ notiData.contentWidth = contentRef.value.getBoundingClientRect().width;
|
|
|
+ notiData.wrapWidth = wrapRef.value.getBoundingClientRect().width;
|
|
|
+
|
|
|
+
|
|
|
+ startAnimate();
|
|
|
+ };
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ init()
|
|
|
+ // 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)`;
|
|
|
+ refAnimation(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) {
|
|
|
+ refAnimation(init);
|
|
|
+ } else {
|
|
|
+ refAnimation(stopAnimate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ return () => (
|
|
|
+ <div
|
|
|
+ ref={wrapRef}
|
|
|
+ class={[styles.wrap, props.isAnimation ? styles.isAnitaion : '']}
|
|
|
+ onMouseenter={() => !props.isAnimation && init()}
|
|
|
+ onMouseleave={() => !props.isAnimation && stopAnimate()}>
|
|
|
+ <div
|
|
|
+ ref={contentRef}
|
|
|
+ style={notiData.contentStyle}
|
|
|
+ class={styles.notice}>
|
|
|
+ {props.text}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|