canvas发送视频弹幕功能效果 html+css+js

举报
北极光之夜。 发表于 2021/06/11 17:17:39 2021/06/11
【摘要】 一.话不多,先上效果:b站超清演示视频地址 二.详细实现步骤:1.先定义HTML标签: <div class="container"> <video src="./vd.mp4" controls loop autoplay ></video> <canvas></canvas> <div class="send">...

一.话不多,先上效果:

b站超清演示视频地址

二.详细实现步骤:

1.先定义HTML标签:

 <div class="container">        
            <video src="./vd.mp4" controls loop autoplay ></video>
            <canvas></canvas>
        <div class="send">
            <input type="text" value="" maxlength="20" placeholder="快来发条弹幕~">
            <button>发送</button>
        </div>
        <input type="color" class="color" value="#FF0000">
    </div>

.container为底层盒子
video为视频
input为输入框
button为发送按钮
.color为颜色选择器

2.老套路全局css样式:

*{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
body{
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: rgb(125, 184, 252);
}

display: flex; flex布局,可以让子元素居中。
3.底层盒子样式:

.container{
    position: relative;
    width: 500px;
    height: 380px;
}

position:relative;相对定位

4.视频样式:

video{
    width: 500px;
    height: 350px;
    object-fit: cover;
    border: 2px outset rgb(211, 211, 211);
}

object-fit: cover;保持原有尺寸比例。但部分内容可能被剪切。

5.输入框与发送按钮样式:

.send{
    width: 500px;
    height: 30px;
}
.send>input{
    float: left;
    height: 100%;
    width: 440px;
    outline:none;
    padding-left: 1em;
    border-radius: 5px 0 0 5px;
    border: 1px solid rgb(155, 155, 155);
}
.send>button{
    float: left;
    height: 100%;
    width: 60px;
    border-radius: 0 5px 5px 0;
    border: none;
    cursor: pointer;
    background-color: rgb(22, 162, 255);
    color: #fff;
    letter-spacing: 3px;
    box-shadow: 1px 1px 1px rgb(75, 75, 75),
    inset 1px 1px 1px  white;
}
.send>button:active{
    box-shadow:inset 1px 1px 1px rgb(75, 75, 75),
     1px 1px 1px  white;
}

outline:none; 去掉轮廓
letter-spacing: 3px; 字间距。
cursor: pointer;鼠标样式为小手

6.颜色选择器和画布样式:

 .color{
    position: absolute;
    bottom: 1px;
    right: 65px;
    width: 20px;
    height: 20px;
}
canvas{
    pointer-events: none;
    position: absolute;
    top: 0;
    left: 0;
}

pointer-events: none;元素永远不会成为鼠标事件的target。

7.开始JavaScript部分,先获取标签和定义变量:

   // 输入框
    const input = document.querySelector("input");
    // 发送按钮
    const btn = document.querySelector("button");
    // 颜色改变
    const color = document.querySelector(".color");
    // 定义canvas
    const canvas = document.querySelector('canvas');
    const ctx = canvas.getContext('2d');
    //当前颜色
    var nowColor = color.value;
     // 保存弹幕的数组
    var texts = [];
    // 画布宽高
    canvas.width = 500;
    canvas.height = 200;

8.当颜色改变,nowColor重新赋值:

 color.addEventListener('change',()=>{
        nowColor = color.value;
    })

9. 点击发送按钮时,获取输出框文本并添加到弹幕数组里,同样,回车也是执行同样的操作:

  btn.addEventListener('click',()=>{
  // 保存输入框文本
        let nowTxt = input.value;
        // 判断文本是否为空
        if(nowTxt!=''){        
        // 清空输入框   
         input.value = '';
         //给弹幕数组添加这一文本
         texts.push({
             txt:nowTxt,
             //该弹幕生成的(x,y)位置
             x:canvas.width,
             // 给个随机值
             y:Math.random()*(canvas.height-16)+16,
             // 弹幕颜色为当前颜色
             color:nowColor
         })            
        }        
    })
 input.addEventListener('keydown',e=>{
       //直接调用点击发送按钮事件
         if(e.keyCode==13){
              btn.click();
         }
    })

10.实现弹幕滚动效果:

  function update(){
  // 清除画布
        ctx.clearRect(0,0,canvas.width,canvas.height);
           // 改变弹幕数组里每一条弹幕位置,x值减少就好
            for(let i=0;i<texts.length;i++){                
                texts[i].x -= 1;
                // 若已移出视频很远了,删除弹幕数组元素
                if(texts[i].x<-500) texts.splice(i,1);
            }
          // 绘制文字
        texts.forEach(item=>{
            ctx.font = "16px Arial";
             //颜色
            ctx.fillStyle = item.color;
            //位置
            ctx.fillText(item.txt,item.x,item.y);
        })       
        // 执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画
        window.requestAnimationFrame(update);
    }
    update();

三.完整代码:

HTML:

<html lang="zh-CN">
<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>auroras</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div class="container">
            <video src="./vd.mp4" controls loop autoplay ></video>
            <canvas></canvas>
        <div class="send">
            <input type="text" value="" maxlength="20" placeholder="快来发条弹幕~">
            <button>发送</button>
        </div>
        <input type="color" class="color" value="#FF0000">
    </div>
    <script src="./index.js"></script>

</body>
</html>

CSS:

*{
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
body{
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: rgb(125, 184, 252);
}
.container{
    position: relative;
    width: 500px;
    height: 380px;
}
video{
    width: 500px;
    height: 350px;
    object-fit: cover;
    border: 2px outset rgb(211, 211, 211);
}
.send{
    width: 500px;
    height: 30px;
}
.send>input{
    float: left;
    height: 100%;
    width: 440px;
    outline:none;
    padding-left: 1em;
    border-radius: 5px 0 0 5px;
    border: 1px solid rgb(155, 155, 155);
}
.send>button{
    float: left;
    height: 100%;
    width: 60px;
    border-radius: 0 5px 5px 0;
    border: none;
    cursor: pointer;
    background-color: rgb(22, 162, 255);
    color: #fff;
    letter-spacing: 3px;
    box-shadow: 1px 1px 1px rgb(75, 75, 75),
    inset 1px 1px 1px  white;
}
.send>button:active{
    box-shadow:inset 1px 1px 1px rgb(75, 75, 75),
     1px 1px 1px  white;
}
.color{
    position: absolute;
    bottom: 1px;
    right: 65px;
    width: 20px;
    height: 20px;
}
canvas{
    pointer-events: none;
    position: absolute;
    top: 0;
    left: 0;
}

JavaScript:

  const input = document.querySelector("input");
    const btn = document.querySelector("button");
    const color = document.querySelector(".color");
    const canvas = document.querySelector('canvas');
    const ctx = canvas.getContext('2d');

    var nowColor = color.value;
    var time = 3;
    var texts = [];
    canvas.width = 500;
    canvas.height = 200;

    color.addEventListener('change',()=>{
        nowColor = color.value;
    })
    btn.addEventListener('click',()=>{
        let nowTxt = input.value;
        if(nowTxt!=''){           
         input.value = '';
         
         texts.push({
             txt:nowTxt,
             x:canvas.width,
             y:Math.random()*(canvas.height-16)+16,
             color:nowColor
         })            
        }        
    })
    input.addEventListener('keydown',e=>{
         if(e.keyCode==13){
              btn.click();
         }
    })
    function update(){
        ctx.clearRect(0,0,canvas.width,canvas.height);
     
            for(let i=0;i<texts.length;i++){                
                texts[i].x -= 1;
                if(texts[i].x<-500) texts.splice(i,1);
            }
   
        texts.forEach(item=>{
            ctx.font = "16px Arial";
            ctx.fillStyle = item.color;
            ctx.fillText(item.txt,item.x,item.y);
        })       
        window.requestAnimationFrame(update);
    }
    update();

    

四.总结:

有一天

开始从平淡日子感受快乐

看到了明明白白的远方

我要的幸福

我要稳稳的幸福

能抵挡末日的残酷

在不安的深夜

能有个归宿

------------------ 陈奕迅《稳稳的幸福》

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。