弹幕效果
js实现弹幕效果
第一种写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
width: 800px;
margin: 0 auto;
padding-bottom: 10px;
background-color: #dfdfdf;
}
#barrage {
position: relative;
height: 500px;
margin-bottom: 10px;
background-color: #000;
overflow: hidden;
}
#barrage .bar-item {
position: absolute;
left: 100%;
white-space: nowrap;
}
#msg {
margin-left: 10px;
width: 400px;
height: 30px;
border: 1px solid #999;
border-right: none;
box-sizing: border-box;
vertical-align: middle;
}
#msg+button {
padding: 0 10px;
height: 30px;
vertical-align: middle;
}
</style>
<script src="./utils.js"></script>
</head>
<body>
<div class="container">
<div id="barrage"></div>
<input type="text" id="msg">
<button id="btn">发送</button>
</div>
<script>
/*
【1】创建对象:把弹幕文字当成对象 function Barrage(){}
【2】描述对象
静态属性:
this.ele
this.text
this.fontSize 每一个字体大小不一样
this.color 颜色不一样
this.top 初始位置不一样
this.speed 每一个字体对象移动的速度不一样
动态方法:
init() 创建元素 绑定事件 执行其他函数
moveDom() 文字移动事件
removeDom() 当移动到最后的时候 把元素清除
【3】使用对象
点击发送的时候调用 new Barrage()
*/
let barrage = document.querySelector('#barrage');
let msg = document.querySelector('#msg');
let btn = document.querySelector('#btn');
btn.onclick = function () {
if(!msg.value){
alert('请输入内容')
return
}
new Barrage(barrage, msg.value);
msg.value="";
}
function Barrage(ele, text) {
this.ele = ele;
this.text = text;
this.fontSize = randomNumber(12, 30);
this.color = randomColor();
this.top = randomNumber(5, this.ele.offsetHeight - this.fontSize);
this.speed = randomNumber(20, 100);
this.init();
}
// 动态方法(重置原型对象)
Barrage.prototype = {
constructor: Barrage,
// init:function(){}
init() {
// let span = document.createElement('span');
// span这个变量只能在init这个函数中使用
// this.span 相当于把这格span属性 定义在实例对象上
// 可以在任意一个方法中使用
this.span = document.createElement('span');
this.span.innerHTML = this.text;
this.span.classList.add('bar-item');
this.span.style.fontSize = this.fontSize + 'px';
this.span.style.color = this.color;
this.span.style.top = this.top + 'px'
this.ele.appendChild(this.span);
this.moveDom()
},
moveDom() {
this.timer = setInterval(() => {
let left = parseInt(getStyle(this.span, 'left'));
// 如果left 小于 span元素宽度的负数的时候 应该停止定时器
// 并且调用移出元素的方法
if (left <= -this.span.offsetWidth) {
clearInterval(this.timer);
this.removeDom()
}
let x = left - 5
this.span.style.left = x + 'px'
}, this.speed)
},
removeDom() {
this.span.remove();
}
}
Object.defineProperty(Barrage.prototype, 'constructor', {
enumerable: false
});
</script>
</body>
</html>
第二种写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
width: 800px;
margin: 0 auto;
padding-bottom: 10px;
background-color: #dfdfdf;
}
#barrage {
position: relative;
height: 500px;
margin-bottom: 10px;
background-color: #000;
overflow: hidden;
}
#barrage .bar-item {
position: absolute;
left: 100%;
white-space: nowrap;
}
#msg {
margin-left: 10px;
width: 400px;
height: 30px;
border: 1px solid #999;
border-right: none;
box-sizing: border-box;
vertical-align: middle;
}
#msg+button {
padding: 0 10px;
height: 30px;
vertical-align: middle;
}
</style>
<script src="./utils.js"></script>
</head>
<body>
<div class="container">
<div id="barrage"></div>
<input type="text" id="msg">
<button id="btn" class="button">发送</button>
</div>
<script>
//1.生成页面元素对象
//属性有:整个弹幕区域、消息框、按钮
//方法有:
// -初始化:获取元素,点击按钮,执行发送方法
// -发送方法,获取消息框内容。实例化弹幕对象
let barrage = document.querySelector('#barrage');
let msg = document.querySelector('#msg');
let btn = document.querySelector('#btn');
let button= document.querySelector('button');
let page = {
ele:'#barrage',
msg:'#msg',
button:'#msg+button',
init(){
this.ele = document.querySelector(this.ele);
this.msg = document.querySelector(this.msg);
this.btn = this.msg.nextElementSibling;
this.btn.onclick = ()=>{
this.send();
}
},
send(){
let msg = this.msg.value;
new Barrage(msg);
this.msg.value="";
}
}
// 2.自定义弹幕对象的构造函数
// (1) 属性:内容、颜色、速度、字体大小、位置
// (2) 方法:
// - 初始化init():创建弹幕对象this.ele,添加内容类名及样式,添加到元素内
// - 运动move():从右往左
// - 移除remove():移除弹幕
function Barrage(msg){
this.color = randomColor();
this.speed = randomNumber(-20,-5);
this.size = randomNumber(12,48);
this.position = randomNumber(10,page.ele.clientHeight-this.size-10);
this.init(msg);
}
Barrage.prototype.init = function(msg){
// 创建弹幕元素
this.ele = document.createElement('span');
this.ele.innerText = msg;
this.ele.className = 'bar-item';
// 定义样式
this.ele.style.color = this.color;
this.ele.style.fontSize = this.size + 'px';
this.ele.style.top = this.position + 'px';
// 写入页面
page.ele.appendChild(this.ele);
// 移动
this.move();
}
Barrage.prototype.move = function(){
this.timer = setInterval(()=>{
let left = this.ele.offsetLeft;
left += this.speed;
if(left <= -this.ele.offsetWidth){
clearInterval(this.timer)
this.remove();
}
this.ele.style.left = left + 'px';
},50);
}
Barrage.prototype.remove = function(){
this.ele.parentNode.removeChild(this.ele);
}
// 页面元素对象的init方法开始执行
page.init();
</script>
</body>
</html>
封装好的脚本
“<script src="./utils.js">”里面的
// 封装一个随机颜色
function randomColor(){
// rag(255,255,255)
return 'rgb('+randomNumber(0,255)+','+randomNumber(0,255)+','+randomNumber(0,255)+')';
}
// 封装任意两个数之间的随机数
function randomNumber(n1,n2){
var num ;
if(n1 > n2){
num = parseInt( Math.random()*(n1-n2+1) + n2);
}else{
num = parseInt( Math.random()*(n2-n1+1) + n1);
}
return num
}
// 获取样式的方法
function getStyle(ele, attr) {
// 兼容的获取方法
var style;
if (window.getComputedStyle) {
style = window.getComputedStyle(ele)[attr];
} else {
style = ele.currentStyle[attr];
}
return style;
}