Open OBKoro1 opened 5 years ago
这是几个月前写的文章,文章下面有很多精彩的讨论,或许能给你一点启发
更好的方式
可以利用canvas或者 CSS 动画来实现弹幕需求,不过文章中的思路,可以参考一下。
canvas
实现弹幕的原理,并不算太复杂,耗费一些时间,怼一怼应该都可以做出来。
setInterval
dom
left
offsetWidth
html
<div class="detailImg"> <img src="url"/> <div id="barrageDiv"> <div id="barrageLayer1"></div> <div id="barrageLayer2"></div> <div id="barrageLayer3"></div> <div id="barrageLayer4"></div> </div> </div> <!--detailImg 设置relative, barrageDiv设置z-index在图片上面,以及图片的位置--> <!-- barrageLayer1~4 主要设置了一个top属性让四个div在各自的水平线上,形成四个通道-->
关于这里的 css 样式,关键点都在上面说了,就注意一下上面通道是怎样形成的,就可以了。具体的样式也就不贴出来了,就根据各自的需求来吧。
要实现弹幕效果肯定需要有数据,这里就是发请求了。
获取数据时,要考虑数据量,一次不可能全部都获取,可以一次获取一部分,当数据要加载完的时候,再次请求数据。
这里要记录数据数据是否全部请求完成,如果请求完成,就可以不再发送数据,直接用之前获取的全部数据就可以了。
弹幕数据获取后,就执行弹幕运行的函数,因为我在写弹幕函数的时候,设置了很多数据状态,这里就大概讲一下实现思路和关键部分代码。
function barrage(){ //第一部分先判断数据是否加载完成 这里是一个定时器,设置为15秒。 //如果数据还未加载完毕,就再次运行请求数据的接口,请求的页数可以 数组/每次请求的条数+1 //数据加载完毕就清除定时器。(我将定时器都保存在vue 组件的data里面) 清除的时候clearInterval(this.data); //定时发射 _this.barrageStatus.divStatus.intervalid=setInterval( selfTime,1100); function selfTime() { if(_this.dataNum>=_this.barrageStatus.data.length){ //当dataNum大于等于数组的数量时,弹幕从头再来一遍 _this.dataNum=0; } //设置四个通道的变量,当这几个变量为false的时候,才可发射 if(divStatus.div1===false){ //这里只演示其中一个变量 divStatus.div1=true; _this.dataNum++; return barrageOut(_this.barrageStatus.data[_this.dataNum-1].content,_this.barrageStatus.data[_this.dataNum-1].commentator.headImgUrl,_this.dataNum); } }; // 创建弹幕内容,自定义弹幕移动速度 function barrageOut(text,imgUrl,num) { //text:弹幕的内容,imgUrl:用户的头像,num:数组的第几个 if(num%4==1){ //根据数组下标 创建对应通道的节点 这里也演示其中一个 barrageLayer=document.getElementById('barrageLayer1'); } // 创建dom内容 定义dom style样式 let divBox = document.createElement('div'); let divBoxImg=document.createElement('span'); let divBoxText=document.createElement('span'); divBox.setAttribute('class','barrageDivClass'); divBoxText.innerHTML=text; divBox.appendChild(divBoxImg); divBoxImg.setAttribute('class','barrageDivClass_img'); divBoxImg.style.backgroundImage=`url(${imgUrl})`; divBox.appendChild(divBoxText); divBox.style.left=document.body.clientWidth+2000+'px';// 初始化left位置,一开始在屏幕的右侧 barrageLayer.appendChild(divBox); // 定时器移动dom,形成弹幕 let time,l=0; time= setInterval(function(){ if(text.length<15){ // 这里可以根据需求自定义弹幕加载的速度 l=l-1; }else{ l=l-2; } //通过减少left属性移动这个div 从右往左移动 divBox.style.left = document.body.clientWidth+l+'px'; let delDiv=()=>{ if(num%4==1){ //在移动弹幕的过程中判断四个通道是否处于闲置状态 这里只演示其中一个 barrageLayer=document.getElementById('barrageLayer1'); if(barrageLayer.childNodes.length<2){ //判断弹幕数量,如果小于2,设为false,上面的定时器可以继续发射弹幕 divStatus.div1=false; }else{ divStatus.div1=true; } } } } if( l <= (0-divBox.offsetWidth-120) ){ if(_this.barrageStatus.divStatus.switch==true){ //弹幕开关 delDiv(); if(l <= (0-divBox.offsetWidth-document.body.clientWidth) ){ //不断减少left属性,当小于这个内容的宽度,并且滚了120的时候 barrageLayer.removeChild(divBox); //移除dom clearInterval(time);//清除这个div的定时器 } }else{ clearInterval(time);//清除这个div的定时器 } } },20) } }
博客链接
博客链接
# 前端弹幕效果实现思路
这是几个月前写的文章 ,文章下面有很多精彩的讨论,或许能给你一点启发
更好的方式
可以利用
canvas
或者 CSS 动画来实现弹幕需求,不过文章中的思路,可以参考一下。# 实现效果:
# 实现原理:
实现弹幕的原理,并不算太复杂,耗费一些时间,怼一怼应该都可以做出来。
setInterval
动态设置dom
的left
属性。offsetWidth
和屏幕的宽度判断元素是否滚动超出屏幕,然后移除 dom。# 实现步骤:
# 1. 首先看一下
html
的结构。关于这里的 css 样式,关键点都在上面说了,就注意一下上面通道是怎样形成的,就可以了。具体的样式也就不贴出来了,就根据各自的需求来吧。
# 2.获取弹幕所需要的数据。
要实现弹幕效果肯定需要有数据,这里就是发请求了。
获取数据时,要考虑数据量,一次不可能全部都获取,可以一次获取一部分,当数据要加载完的时候,再次请求数据。
这里要记录数据数据是否全部请求完成,如果请求完成,就可以不再发送数据,直接用之前获取的全部数据就可以了。
# 3.执行弹幕的函数。
弹幕数据获取后,就执行弹幕运行的函数,因为我在写弹幕函数的时候,设置了很多数据状态,这里就大概讲一下实现思路和关键部分代码。
# 弹幕函数包括的功能:
# 点个Star 支持我一下~
博客链接