Heim  >  Artikel  >  Web-Frontend  >  Wie HTML Canvas verwendet, um die Sperrfunktion zu implementieren

Wie HTML Canvas verwendet, um die Sperrfunktion zu implementieren

墨辰丷
墨辰丷Original
2018-06-04 15:00:471988Durchsuche

Dieser Artikel stellt hauptsächlich vor, wie HTML Canvas zur Implementierung der Sperrfunktion verwendet. Ich hoffe, dass er für alle hilfreich ist.

Einführung

Ich musste vor kurzem einen Sperrfeuerspieler bauen, als ich einen großen Auftrag erledigte. Ich habe den Quellcode anderer Leute ausgeliehen und selbst einen neu implementiert. Die Demonstration ist wie folgt:

Die Hauptfunktionen sind

Sperrfeuer senden
Sperrfeuerfarbe, Geschwindigkeit und Art einstellen
Sperrfeuer anzeigen

Bekannte Mängel:

Kann nicht im Vollbildmodus angezeigt werden

Die Leinwand ist nicht adaptiv
Es gibt keine benutzerdefinierte Spielersteuerung
Die entsprechende Sperre wird nicht entsprechend der Wiedergabezeit angezeigt
Die Sperre kann nicht mit der Maus bewegt werden
Bereits bekannte Mängel werden in Zukunft behoben. Der Quellcode von Barrage-Playern, der im Internet zu finden ist, macht im Allgemeinen nur rollendes Barrage und kein statisches Barrage. Hier habe ich speziell die Implementierung von statischem Barrage hinzugefügt.

Canvas zeichnet Text und Text-Scroll-Effekt

Der Kern des gesamten Players besteht darin, Text zu zeichnen und Text-Scrolling für Text auf Canvas zu animieren Es gibt keine gute Animationsunterstützung, daher können Sie sie nur selbst implementieren. Die Idee bei der Implementierung besteht darin, den Bildschirm ständig zu löschen und den Text dann neu zu schreiben erreicht wird.

Fügen Sie zunächst das Video-Video-Tag und das Canvas-Tag in die HTML-Datei ein.

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

Stellen Sie den Positionsstil des Canvas-Tags auf position:absolute ein und dann überlappen sich Video und Leinwand und es sieht aus wie ein Sperrfeuer-Player. Fügen Sie dann der Leinwand Inhalte im Zusammenhang mit Sperrfeuern hinzu, rufen Sie zunächst die relevanten Informationen der Leinwand ab und legen Sie die Schriftgröße und den Schriftstil der Leinwand fest.

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;
            }
        }
    }
}

Initialisierung von Das erstellte Sperrobjekt wird definiert. Es werden verschiedene Parameter, einschließlich Inhalt, Farbe, Bewegungsart und Geschwindigkeit, definiert, um die Lockerung der Sperrfunktion zu steuern. Jedes Mal, wenn die Methode move() gestartet wird, wird nach links gescrollt um ein Pixel der Einheitsgeschwindigkeit.
Nachdem die Konstruktion des Sperrobjekts abgeschlossen ist, geben Sie das Thema und die Animationsproduktion ein und geben Sie direkt den Code ein.

//循环擦写画布实现动画效果
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)

Alle 20 ms löschen, ctx.clearRect (0,0,c_width,c_height); besteht darin, die gesamte aktuelle Leinwand zu löschen, dann ctx.save() zu verwenden, um die aktuelle Leinwand zu speichern und dann die Sperrliste zu durchlaufen (msgs ist die Sperrliste, wenn jede Sperrschicht gesendet wird). Die Barrage-Instanz wird der Liste hinzugefügt) und dann separat entsprechend dem Standard-Barrage-Stil oder dem statischen Barrage-Stil verarbeitet. Wenn es sich um eine Barrage des Standardstils handelt, wird sie wie folgt verarbeitet

//处理默认弹幕样式
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();
        }
    }  
}

Erstens, wenn die Barrage-Instanz nicht festgelegt wird Das linke Attribut wird ihm dann zugewiesen. Wenn die Barrage-Instanz die Canvas verlassen hat, wird sie auf null gesetzt, um Speicher zu sparen. Andernfalls wird die move()-Methode der Barrage-Instanz aufgerufen, um den Wert zu ändern des linken Attributs, und dann wird die Farbe des Textes festgelegt. Schreiben der ersten Ebene: Neuer Text, Leinwand wiederherstellen. Damit ist ein Frame der Animation abgeschlossen.

Die Implementierungsmethode für statisches Sperrfeuer ist wie folgt

//处理静止弹幕样式
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;
        }
    }
}

Verschieben Sie zunächst den Basispunkt der Leinwand in die Mitte der Leinwand Es ist zu beachten, dass zu diesem Zeitpunkt im Vergleich zu einer neuen Leinwand die Methode clearRect() der ursprünglichen Leinwand nicht mehr auf diese Leinwand anwendbar ist. Stellen Sie dann die Textausrichtung auf zentrierte Ausrichtung ein, legen Sie den Textstil fest und füllen Sie den Text. Da das Sperrfeuer statisch ist, besteht keine Notwendigkeit, es zu lockern, aber auch das statische Sperrfeuer verschwindet. Sie müssen ein Flag setzen, damit es regelmäßig verschwindet. Um hier keine zusätzlichen Attribute zu belegen, verwenden wir das linke Attribut direkt als Flag. Wir dekrementieren auch das linke Attribut, spiegeln die Verringerung jedoch nicht im Canvas wider. Wenn left den Schwellenwert erreicht, verwenden wir die Methode ctx.clearRect() um das Sperrfeuer zu beseitigen. Auf diese Weise wird die Verarbeitung statischer Sperrfeuer realisiert.

Andere Leute, die über gewisse Kenntnisse im Festlegen von Farben und Stilen verfügen, sollten es leicht beherrschen. Ich werde es hier nicht vorstellen. Schauen Sie sich einfach den ausführbaren Code an und verstehen Sie ihn.

Zusammenfassung

Dieses Projekt verwendet hauptsächlich Leinwand zum Zeichnen von Text und zur Textbeschleunigung. Die wichtigsten verwendeten Methoden sind

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

Ursprünglich konnte ich Save() und Restore() nicht verstehen, aber jetzt habe ich ein wenig Verständnis dafür, wenn Sie den Canvas-Status ändern. Die Canvas ist nicht mehr die Original-Canvas Speichern Sie also vor dem Ändern des Canvas-Status den Canvas-Status und wechseln Sie nach Abschluss der Arbeit zum ursprünglichen Canvas-Status und fahren Sie mit der Arbeit fort. Wenn ich beispielsweise mit statischen Sperren umgehe und den Basispunkt der Leinwand ändere, gilt die ursprüngliche Methode zum Löschen der Leinwand nicht mehr für die aktuelle Leinwand und ich kann nur eine andere Löschmethode für die aktuelle Leinwand verwenden. Kehren Sie dann zur ursprünglichen Leinwand zurück.

Ausführbarer 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">
    .pickp{
        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>
    <p id="barrageplayer">
        <canvas id="cv_video" width="900px" height="450px"></canvas>
        <video id="v_video" src="test.MP4" controls type="video/mp4"></video>
    </p>
    <p id="barrageinput">
        <p>
            <input type="text" id="smsg" placeholder="请输入弹幕内容"/>
            <button id="send"> 发送</button>
        </p>
        <p id="colorpick">
            <p class="pickp" id="white"></p>
            <p class="pickp" id="red"></p>
            <p class="pickp" id="yellow"></p>
            <p class="pickp" id="blue"></p>
            <p class="pickp" id="green"></p>
        </p>
        <p 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">静止底部
        </p>
        <p 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
        </p>
        <p id="stylepick"></p>
    </p>
    <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>

Zusammenfassung: Das Obige ist der gesamte Inhalt dieses Artikels, ich hoffe, er wird für das Lernen aller hilfreich sein.

Verwandte Empfehlungen:

Detaillierte Erläuterung des H5+Canvas-Anwendungsfalls

So verwenden Sie Vue+Canvas, um die mobile Handschriftpad-Funktion zu implementieren

js+canvasimplementieren Sie die Schiebepuzzle-Bestätigungscodefunktion

Das obige ist der detaillierte Inhalt vonWie HTML Canvas verwendet, um die Sperrfunktion zu implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn