Home  >  Article  >  Web Front-end  >  How to use HTML to implement scrolling barrage function

How to use HTML to implement scrolling barrage function

php中世界最好的语言
php中世界最好的语言Original
2018-01-17 09:55:1410814browse


This time I will show you how to use HTML to implement the scrolling barrage function. What are the precautions for implementing the rolling barrage function in HTML? The following is a practical case. Let’s take a look.

The main functions are; sending barrages, setting the color, speed and type of barrages, and displaying barrages

Known defects: Cannot be full screen

canvas does not do customization Adaptation
There is no custom player control
The corresponding barrages are not displayed according to the playback time
The barrages cannot be hovered
Known defects will be improved in the future. The source code of barrage players that can be found on the Internet generally only makes rolling barrage and not static barrage. Here I specially added the implementation of static barrage.

Canvas draws text and text scrolling effect

The core of the entire player is to draw text and animate text scrolling. There is no good animation support for text in canvas, and you can only use it yourself Realization, the idea of ​​​​implementation is to continuously clear the screen and then rewrite the text. When the frequency of screen clearing and rewriting reaches 24fps, the animation will be smooth.

First add video in the HTML filevideo tag and canvas canvas tag

<div id="barrageplayer">
    <canvas id="cv_video" width="900px" height="450px"></canvas>
    <video id="v_video" src="test.MP4" controls type="video/mp4"></video>
</div>

Set the position style of the canvas tag to position:absolute and then the video and canvas will overlap. Together, it looks like a barrage player. Then add barrage-related content to the canvas. First, obtain the relevant information of the canvas and set the font size and font style of the canvas.

var c=document.getElementById("cv_video");
//获取画布大小
var c_height=c.height;
var c_width=c.width;
//获取画布
ctx=c.getContext("2d");
//设置字体样式
ctx.font="25px DengXian";
画布信息已经获取和设置,巧妇难为无米之炊,接着我们就要构造弹幕对象,使用的构造模式是动态原型模式
//弹幕对象
function Barrage(content,color,type,speed){
    this.content=content;
    this.color=color;
    this.type=type;
    this.speed=speed;
    if(this.type=="default"){
        this.height=parseInt(Math.random()*c_height)+10;
    }else if (this.type=="static top"){
        this.height=parseInt((c_height/2)-Math.random()*c_height/2)+10;
    }else if (this.type=="static bottom"){
        this.height=parseInt((c_height/2)+Math.random()*c_height/2)+10;
    }
    if(typeof this.move!="function"){
        Barrage.prototype.move=function(){
            if(this.type=="default"){
                this.left=this.left-this.speed;
            }
        }
    }
}

The constructed barrage object initializes various parameters, including content, color, and motion type. and speed. The move() method is defined to control the easing of the barrage. Each time the move() method is launched, it scrolls to the left by one pixel of unit speed.

After the construction of the barrage object is completed, enter the theme and animation production, directly enter the code

//循环擦写画布实现动画效果
setInterval(function(){
    ctx.clearRect(0,0,c_width,c_height);
    ctx.save();
    for(var i=0;i<msgs.length;i++){
        if(msgs[i]!=null){
            if(msgs[i].type=="default"){
                handleDefault(msgs[i]);
            }else{
                handleStatic(msgs[i]);
           }
        }
    }
},20)

Erase is executed every 20ms, ctx.clearRect(0,0,c_width,c_height); is to Clear the entire current canvas, then use ctx.save() to save the current canvas, and then traverse the barrage list (msgs is the barrage list. Each time a barrage is sent, the barrage instance will be added to the list). Then process them separately according to the default style of barrage or the static style of barrage. If it is a barrage of the default style, it will be processed according to the following method

//处理默认弹幕样式
function handleDefault(barrage){
    if(barrage.left==undefined||barrage.left==null){
        barrage.left=c.width;
    }else{
         if(barrage.left<-200){
            barrage=null;
        }else{
            barrage.move()
            ctx.fillStyle=barrage.color;
            ctx.fillText(barrage.content,barrage.left,barrage.height)
            ctx.restore();
        }
    } 
}

First, if the barrage instance does not set the left attribute, the width of the canvas will be assigned to it. If the barrage instance has exited the canvas, it will be set to null. To save memory, otherwise call the move() method of the barrage instance to change the value of the left attribute, then set the color of the text, write new text at the first level, and restore the canvas. This completes one frame of animation.

The implementation method for static barrage is as follows

//处理静止弹幕样式
function handleStatic(barrage){
    ctx.moveTo(c_width/2,barrage.height);
    ctx.textAlign="center";
    ctx.fillStyle=barrage.color;
    ctx.fillText(barrage.content,c_width/2,barrage.height);
    if(barrage.left==undefined||barrage.left==null){
        barrage.left=c.width;
    }else{
        if(barrage.left<-200){
            ctx.fillText("",c_width/2,barrage.height);               
            barrage=null;
            //ctx.restore();
            ctx.clearRect(0,0,c_width,c_height);       
        }else{
            barrage.left=barrage.left-6;
        }
    }
}

First move the base point of the canvas to the center of the canvas. It should be noted that at this time, a new canvas is generated relative to the original canvas. The clearRect() method is no longer applicable to this canvas. Then set the text alignment to center alignment, set

text style , and fill the text. Because the barrage is static, there is no need to ease it, but the static barrage will also disappear. You need to set a flag to make it disappear regularly. In order not to occupy additional attributes here, we directly use the left attribute as the flag. We also decrement the left attribute, but do not reflect the decrease in the canvas. When left reaches the threshold, use the ctx.clearRect() method to clear the barrage. Clear. In this way, the processing of static barrage is realized.

Other people who have a certain foundation in setting colors and styles should be able to easily master it. I won’t introduce it here. Just look at the runnable code and understand it yourself.

Summary

This project mainly uses canvas for text drawing and text easing animation. The main methods used are

canvasDom.getContext()
canvas.save()/canvas.restore()
canvas.clearRect()
canvas.moveTo()


Originally I couldn’t understand save() and restore(), but now I have a little understanding. When you change the canvas state, the current canvas is no longer the original canvas, so before modifying the canvas state First save the canvas state, switch the canvas state, and after completing the work, return to the original canvas state and continue working. For example, when I deal with static barrages and change the base point of the canvas, the original canvas clearing method no longer applies to the current canvas, and I can only use another clearing method in the current canvas. Then return to the original canvas.

Runnable Code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<style type="text/css">
    .pickdiv{
        width: 30px;
        height: 30px;
        cursor: pointer;
        border: 2px solid gray;
        display: inline-block;
    }
    #white{
        background: white;
    }
    #red{
        background:#ff6666;
    }
    #yellow{
        background:#ffff00;
    }
    #blue{
        background:#333399;
    }
    #green{
        background:#339933;
    }
    #cv_video{
        position: absolute;
        z-index: 1;
    }
    #barrageplayer{
        position: relative;
        display: block;
        width: 900px;
        height: 500px;
    }
    #v_video{
        position: absolute;
        width: 100%;
        height: 100%;
        z-index: 0;
    }
</style>
<body>
    <div id="barrageplayer">
        <canvas id="cv_video" width="900px" height="450px"></canvas>
        <video id="v_video" src="test.MP4" controls type="video/mp4"></video>
    </div>
    <div id="barrageinput">
        <div>
            <input type="text" id="smsg" placeholder="请输入弹幕内容"/>
            <button id="send"> 发送</button>
        </div>
        <div id="colorpick">
            <div class="pickdiv" id="white"></div>
            <div class="pickdiv" id="red"></div>
            <div class="pickdiv" id="yellow"></div>
            <div class="pickdiv" id="blue"></div>
            <div class="pickdiv" id="green"></div>
        </div>
        <div id="typepick">
            <input type="radio" name="type" value="default">默认
            <input type="radio" name="type" value="static top">静止顶部
            <input type="radio" name="type" value="static bottom">静止底部
        </div>
        <div id="speedpick">
            <input type="radio" name="speed" value="1">1X
            <input type="radio" name="speed" value="2">2X
            <input type="radio" name="speed" value="3">3X
        </div>
        <div id="stylepick"></div>
    </div>
    <script>
        var c=document.getElementById("cv_video");
        var typeDom=document.getElementsByName("type");
        var speedDom=document.getElementsByName("speed");
        var colorpick=document.getElementById("colorpick");
        var smsg=document.getElementById("smsg");
        var color="#white";
        var speed=1;
        var type="default";
        var msgs=[];
        //获取画布大小
        var c_height=c.height;
        var c_width=c.width;
        //获取画布
        ctx=c.getContext("2d");
        ctx.font="25px DengXian";
        //处理颜色选择
        colorpick.addEventListener(&#39;click&#39;,function(event){
            switch(event.target.id){
                case "white":
                    color="white";
                    break;
                case "red":
                    color="#ff6666";
                    break;
                case "yellow":
                    color="#ffff00";
                    break;
                case "green":
                    color="#339933";
                    break;
                case "blue":
                    color="#333399";
                    break;
            }
        })
        //处理发送弹幕
        document.getElementById("send").onclick=function(){
            var text=smsg.value;
            for(var i=0;i<typeDom.length;i++){
                if(typeDom[i].checked){
                    type=typeDom[i].value;
                    break;
                }
            }
            for(var i=0;i<speedDom.length;i++){
                if(speedDom[i].checked){
                    speed=2*parseInt(speedDom[i].value);
                    break;
                }
            }
            var tempBarrage=new Barrage(text,color,type,speed);
            msgs.push(tempBarrage);
        }
        //
        //弹幕功能部分代码
        //
        //弹幕对象
        function Barrage(content,color,type,speed){
            this.content=content;
            this.color=color;
            this.type=type;
            this.speed=speed;
            if(this.type=="default"){
                this.height=parseInt(Math.random()*c_height)+10;
            }else if (this.type=="static top"){
                this.height=parseInt((c_height/2)-Math.random()*c_height/2)+10;
            }else if (this.type=="static bottom"){
                this.height=parseInt((c_height/2)+Math.random()*c_height/2)+10;
            }
            if(typeof this.move!="function"){
                Barrage.prototype.move=function(){
                    if(this.type=="default"){
                        this.left=this.left-this.speed;
                    }
                }
            }
        }
        //循环擦写画布实现动画效果
        setInterval(function(){
            ctx.clearRect(0,0,c_width,c_height);
            ctx.save();
            for(var i=0;i<msgs.length;i++){
                if(msgs[i]!=null){
                    if(msgs[i].type=="default"){
                        handleDefault(msgs[i]);
                    }else{
                        handleStatic(msgs[i]);
                    }
                }
            }
        },20)
    //处理默认弹幕样式
    function handleDefault(barrage){
        if(barrage.left==undefined||barrage.left==null){
            barrage.left=c.width;
        }else{
            if(barrage.left<-200){
                barrage=null;
            }else{
                barrage.move()
                ctx.fillStyle=barrage.color;
                ctx.fillText(barrage.content,barrage.left,barrage.height)
                ctx.restore();
            }
        } 
    }
    //处理静止弹幕样式
    function handleStatic(barrage){
        ctx.moveTo(c_width/2,barrage.height);
        ctx.textAlign="center";
        ctx.fillStyle=barrage.color;
        ctx.fillText(barrage.content,c_width/2,barrage.height);
        if(barrage.left==undefined||barrage.left==null){
            barrage.left=c.width;
        }else{
            if(barrage.left<-200){
                ctx.fillText("",c_width/2,barrage.height);               
                barrage=null;
                //ctx.restore();
                ctx.clearRect(0,0,c_width,c_height);       
            }else{
                barrage.left=barrage.left-6;
            }
        }
    }
    </script>
</body>
</html>

I believe you have mastered the methods after reading these cases. For more exciting information, please pay attention to other related articles on the php Chinese website!

Related reading:

How to insert a video into an HTML webpage

How to make an HTML text box read-only effect

How to use HTML+CSS to display the secondary menu bar by swiping the mouse over it

The above is the detailed content of How to use HTML to implement scrolling barrage function. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn