手写弹幕轮播(小程序)

321 阅读1分钟

公司春节活动用到弹幕轮播,没找到合适的,就自己手写了一个。

js部分:

第一步:处理服务器获取的数据

/**
   * 处理服务器获取的弹幕数据
   */
  handleData(data){
    console.log(data)
    this.data.classNUm = 0
    // {id:'1',text:'发',thumbsUp:'1000',width:''},
    this.data.localWishData = JSON.parse(JSON.stringify(data.data))
    this.data.barrage = data.data
    this.pushBarrageData()
   let everyNum  = parseInt(this.data.barrage.length/5)
  //  console.log(this.data.barrage)
   this.data.barrage = JSON.parse(JSON.stringify(this.data.barrage))


   for(let i=0;i<this.data.arrayName.length;i++){
     let name = this.data.arrayName[i]+'Array'
    //  将数据分成几份
    if(i == this.data.arrayName.length-1){
      this.data[name] = this.data.barrage.slice(everyNum*i,this.data.barrage.length)

    }else{
      this.data[name] = this.data.barrage.slice(everyNum*i,everyNum*(i+1))

    }
    //  处理每个宽度
     this.handleClass(this.data.arrayName[i],this.data[name])
     //渲染到界面的取五条
     this.data['real'+this.data.arrayName[i]+'Array'] = JSON.parse(JSON.stringify(this.data[name].slice(0,5)))
     //获取取到公用数据的长度
     this.data[this.data.arrayName[i]+'GetNum'] = this.data['real'+this.data.arrayName[i]+'Array'].length
     //存储所有渲染界面的数据
     this.data.allDataArray.push(this.data['real'+this.data.arrayName[i]+'Array'])
    //  console.log(this.data[name])
   }

第二步:因为我的需求处理的数据是25条,所以要确保25条

pushBarrageData(){
    if(this.data.barrage.length<25){
      if(this.data.barrage.length>=25-this.data.localWishData.length){
        let change = this.data.localWishData.slice(0,(25-this.data.localWishData.length))
        this.data.barrage = [...this.data.barrage,...change]
       }else{
        this.data.barrage = [...this.data.barrage,...this.data.localWishData.slice(0,this.data.localWishData.length)]
        this.pushBarrageData()
       }
    }  
  },

第三步:动态计算每个弹幕的宽度

handleClass(text,array){
  // console.log(array)

  
 array.forEach((item,index)=>{
  let strings = 0
  let nums = 0;
  //  item.comment.forEach((items)=>{
      
  //  })
   for(let i = 0;i<item.comment.length;i++){
     let items = item.comment[i]
    if(isNumber(items)){
      nums++
    }else{
    strings++
  }
  }
   item.id= text+'-'+index
   item.width=strings*30+46*2+11*String(item.lokeCount).length+25+7+nums*15
   if(index>0){
     item.left = (parseInt(array[index-1].width)+parseInt(array[index-1].left))+55
   }else{
     let reduce = Math.round(Math.random()*100)
     item.left = 750-reduce
   }    
  //  this.data.classNUm++
   }) 
} ,

第四步:因为弹幕可能包含数字,字母,文字,所以弹幕字符所占宽度不一样

function isNumber(val) {
  var regPos = /^\d+(\.\d+)?$/; //非负浮点数
  var regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; //负浮点数
  if(regPos.test(val) || regNeg.test(val)) {
      return true;
      } else {
      return false;
      }
  }

补充:还可以通过以下,判断字节数

String.prototype.gblen = function() { 
  var len = 0;  
  var str = ''
  for (var i=0; i<this.length; i++) {  
    if (this.charCodeAt(i)>127 || this.charCodeAt(i)==94) {  
       len += 2;  
     } else if( isNumber(this[i])){
      len +=1.5;  

     } else{ 
       
       len +=1;  
     } 
     str+=this[i]
     if(parseInt(len/2)>=28) {
        return str+'...'
     }
   }  
   return str
}

第四步:开始移动弹幕box

animaMove(){
  this.data.lastBarrage = this.data.nextBarrage
  this.data.nextBarrage = this.data.lastBarrage-1000
  this.animate('.barrage-box',[
    {left:this.data.lastBarrage+'rpx'},
    {left:this.data.nextBarrage+'rpx'},
  ],6000,function(){
    // this.clearAnimation('.barrage-box',()=>{
      this.animaMove()
    // })
    
  }.bind(this))
},

第五步:每500毫秒判断一次,如果第二条消失了,再新添加两条,删除最新的两条

handleAnimaTime(){
  let _self = this
  this.data.moveInter = setInterval(()=>{
    wx.createSelectorQuery().select('.barrage-box').boundingClientRect(function(rect){
      for(let i = 0;i<5;i++){
        if(_self.data['real'+_self.data.arrayName[i]+'Array'][1].width+_self.data['real'+_self.data.arrayName[i]+'Array'][1].left<=-(rect.left*750 / wx.getSystemInfoSync().windowWidth)){
          _self.data['real'+_self.data.arrayName[i]+'Array'].splice(0,2)
          _self.handlePush(_self.data.arrayName[i])
          _self.handlePush(_self.data.arrayName[i])
          _self.setData({
            allDataArray:_self.data.allDataArray
          })
         }
      }
}).exec()
  },500)
},

以下为wxml代码

<view class='barrage-box'  style="left:{{barrageLeft}}rpx;top:{{barrageTop}}rpx"  >
           <view class='every-list' wx:for="{{allDataArray}}" wx:for-item='allData' >
                 <view wx:for="{{allData}}" class='list-text' style="width:{{item.width}}rpx;left:{{item.left}}rpx">
                      <view bindtap="clickText" data-get-item='{{item}}'>{{item.comment}}</view>
                      <view class='give-num-click'  bindtap="clickGiveLike"  data-get-index='{{index}}' data-get-item='{{item}}'></view>
                      <view class='give-like-click'>
                              <view class='give-like-box'>
                                  <image class='give-like give-like-{{item.id}}'  src='{{item.src}} '></image>
                               </view>
                           <view class='thumbs-Up'>{{item.likeCount}}</view>
                      </view>
                    
                  </view>
            </view>
            
      </view>