公司春节活动用到弹幕轮播,没找到合适的,就自己手写了一个。
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>