写了一个简单的vue弹幕生成指令:v-move

113 阅读1分钟

1,导入vue 声明随机数生成函数

import Vue from 'vue' function random(min, max) { return Math.floor(Math.random() * (max - min)) + min; }

2,使用vue自定义指令

Vue.directive('move',
    {
   
     // 指令与元素成功绑定时(一上来)调用
     bind(element,binding) {
       
     },
     // 指令所在元素被插入页面时调用
     inserted(element,binding) {
        // const conut = [6,36, 66,96,126,156]
        // 获取弹幕元素的高度
        const min = element.offsetHeight
        // 获取容纳弹幕盒子高度
        const max = element.parentElement.offsetHeight 
        console.log(min,max);
        // 弹幕行与行距离
        const gap = 6
        // 每一行都弹幕距离上一行px 最后一行弹幕距离底部至少6px
        // console.log(Math.floor((max-gap)/(min+gap))); // 5
        const num = Math.floor((max-gap)/(min+gap))
 
        // 当最后一行弹幕距离底部大于 gap 时 将多余出来的间隔 平均分配到每行弹幕中去
        const num2 = ((max-gap)/(min+gap) - num) * min / num
        // 存放弹幕margintop值的数组
        const arr = []
        for (let index = 0; index < num; index++) {
           // 将每次累加后的值存放到数组中
            arr.push(arr.reduce((pro)=>{
              return pro === gap ? pro+min+gap : pro+min+gap+num2
            },gap))
        }
        // console.log('arr',arr);
        // 随机抽取一行
        let top  = random(0, arr.length)
        // console.log(top);
        const setTop = localStorage.getItem(`top`)  || 0
        // 行数连续出来现两次 进行处理
        if((setTop-top) === 0){
            top =  top>2? top-2 :  top+2>6 ? 2 : top+2
        }
        // 将这一行存放到本地中,防止连续出现两次
        localStorage.setItem(`top`,top)
        // 给这一行的弹幕设置margintop值
        element.style.marginTop= arr[top] +'px'
        // 提升弹幕定位优先级
        element.style.zIndex = -5
        // console.log(element.getBoundingClientRect(),random(min, max) +'px');
    //   console.log(element.offsetWidth === 198 && element.remove());
    // 获取容器宽度
    let variable = element.parentElement.offsetWidth
    // 开启定时器
        const timer  = setInterval(()=> {
          element.style.zIndex = 'auto'
          // 将弹幕推出容器外
            element.style.marginLeft = variable+'px'
            // 定时器执行,弹幕开始运动
            if(-element.offsetLeft<element.parentElement.offsetWidth){
                variable-=0.5
            }else {
            // 当弹幕完全超出了父元素,将弹幕销毁,并清除定时器
                clearInterval(timer)
                element.remove()
            }
        })
     },
     // 指令所在模板被重新解析是调用
     update(element,binding){
 
     }
   }

)