Maison interface Web tutoriel HTML Comment HTML utilise Canvas pour implémenter la fonction de barrage

Comment HTML utilise Canvas pour implémenter la fonction de barrage

Jun 04, 2018 pm 03:00 PM
canvas html 实现

Cet article présente principalement comment HTML utilise Canvas pour implémenter la fonction de barrage. J'espère qu'il sera utile à tout le monde.

Introduction

J'ai récemment eu besoin de faire un joueur de barrage alors que je faisais un gros travail. J'ai emprunté le code source d'autres personnes et en ai réimplémenté un moi-même. La démonstration est la suivante

Les principales fonctions sont<.>

Envoyer le barrage

Définir la couleur, la vitesse et le type du barrage
Afficher le barrage

Défauts connus :

Ne peut pas être en plein écran

Le canevas n'est pas adaptatif

Il n'y a pas de contrôle personnalisé du joueur
Le barrage correspondant ne s'affiche pas en fonction du temps de lecture
Le barrage ne peut pas être survolé
Les défauts déjà connus seront améliorés à l'avenir. Les codes sources des joueurs de barrage que l'on peut trouver sur Internet ne font généralement que des barrages roulants et non des barrages statiques. Ici j'ai spécialement ajouté l'implémentation du barrage statique.

Canvas dessine du texte et un effet de défilement de texte

Le cœur de l'ensemble du lecteur est de dessiner du texte et d'animer le défilement du texte pour le texte dans le canevas. Il n'existe pas de bon support d'animation, vous ne pouvez donc l'implémenter que par vous-même. L'idée de l'implémenter est d'effacer constamment l'écran, puis de réécrire le texte. Lorsque la fréquence d'effacement et de réécriture de l'écran atteint 24 ips, l'animation est fluide. sera atteint.

Ajoutez d'abord la balise vidéo vidéo et la balise canevas au fichier HTML

<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>
Copier après la connexion

Définissez le style de position de la balise canevas sur position : absoluEnsuite, la vidéo et le canevas se chevauchent, et cela ressemble à un joueur de barrage. Ajoutez ensuite du contenu lié au barrage au canevas, obtenez d'abord les informations pertinentes du canevas et définissez la taille et le style de police du canevas

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;
            }
        }
    }
}
Copier après la connexion

barrage construit L'objet initialise divers paramètres, notamment le contenu, la couleur, le type de mouvement et la vitesse. La méthode move() est définie pour contrôler l'atténuation du barrage. Chaque méthode move() défile vers la gauche d'un pixel de vitesse unitaire.

Une fois la construction de l'objet barrage terminée, entrez le thème et la production d'animation, entrez directement le 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)
Copier après la connexion

Effacez et écrivez toutes les 20 ms , ctx .clearRect(0,0,c_width,c_height); efface tout le canevas actuel, puis utilise ctx.save() pour enregistrer le canevas actuel, puis parcourt la liste de barrages (msgs est la liste de barrages, lorsque chacun est envoyé Le barrage ajoutera l'instance de barrage à la liste), puis la traitera séparément selon le barrage de style par défaut ou le barrage de style statique. S'il s'agit d'un barrage de style par défaut, il sera traité selon la méthode suivante

//处理默认弹幕样式
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();
        }
    }  
}
Copier après la connexion

Premièrement, si l'instance de barrage le fait ne pas définir l'attribut left Ensuite, donnez-lui la largeur du canevas. Si l'instance de barrage a quitté le canevas, définissez-la sur null pour économiser de la mémoire. Sinon, appelez la méthode move() de l'instance de barrage pour modifier la valeur de gauche. attribut, puis définissez la couleur du texte. Niveau 1 Écrivez un nouveau texte et restaurez le canevas. Ceci termine une image de l’animation.

La méthode de mise en œuvre du barrage statique est la suivante

//处理静止弹幕样式
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;
        }
    }
}
Copier après la connexion

Déplacez d'abord le point de base du canevas vers le centre du canevas . Il convient de noter qu'à ce moment, un nouveau canevas est généré et la méthode clearRect() du canevas d'origine n'est plus applicable à ce canevas. Ensuite, définissez l'alignement du texte sur l'alignement central, définissez le style du texte et remplissez le texte. Le barrage étant stationnaire, il n'est pas nécessaire de le ralentir, mais les barrages statiques disparaîtront également. Vous devez installer un drapeau pour les faire disparaître régulièrement. Afin de ne pas occuper d'attributs supplémentaires ici, nous utilisons directement l'attribut left comme indicateur. Nous décrémentons également l'attribut left, mais ne reflétons pas la diminution dans le canevas. Lorsque left atteint le seuil, utilisez la méthode ctx.clearRect(). pour dégager le barrage. De cette façon, le traitement du barrage statique est réalisé.

Les autres personnes qui ont une certaine base dans la définition des couleurs et des styles devraient être capables de le maîtriser facilement. Je ne le présenterai pas ici. Il suffit de regarder le code exécutable et de le comprendre vous-même.

Résumé

Ce projet utilise principalement un canevas pour le dessin de texte et l'animation d'assouplissement de texte. Les principales méthodes utilisées sont

<. 🎜>

canvasDom.getContext()
canvas.save()/canvas.restore()
canvas.clearRect()
canvas.moveTo()
Copier après la connexion

À l'origine, je ne comprenais pas save() et restaurer(), mais maintenant j'ai un peu compris. Lorsque vous changez l'état du canevas, le canevas actuel n'est plus le canevas actuel. toile d'origine, donc avant de modifier l'état du canevas, enregistrez l'état du canevas et changez d'état du canevas. Après avoir terminé le travail, revenez à l'état du canevas d'origine et continuez à travailler. Par exemple, lorsque je gère des barrages statiques et que je change le point de base du canevas, la méthode de nettoyage du canevas d'origine ne s'applique plus au canevas actuel et je ne peux utiliser qu'une autre méthode de nettoyage dans le canevas actuel. Revenez ensuite à la toile d'origine.

Code exécutable

<!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>
Copier après la connexion

Résumé : ce qui précède est l'intégralité du contenu de cet article, j'espère qu'il sera utile à l'étude de chacun .

Recommandations associées :

Explication détaillée du cas d'utilisation de H5+Canvas

Comment utiliser Vue+canvas pour implémenter la fonction de bloc d'écriture mobile

js+canvasimplémente la fonction de code de vérification du puzzle coulissant

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Bordure de tableau en HTML Bordure de tableau en HTML Sep 04, 2024 pm 04:49 PM

Guide de la bordure de tableau en HTML. Nous discutons ici de plusieurs façons de définir une bordure de tableau avec des exemples de bordure de tableau en HTML.

Tableau imbriqué en HTML Tableau imbriqué en HTML Sep 04, 2024 pm 04:49 PM

Ceci est un guide des tableaux imbriqués en HTML. Nous discutons ici de la façon de créer un tableau dans le tableau ainsi que des exemples respectifs.

Marge gauche HTML Marge gauche HTML Sep 04, 2024 pm 04:48 PM

Guide de la marge HTML gauche. Nous discutons ici d'un bref aperçu de la marge gauche HTML et de ses exemples ainsi que de son implémentation de code.

Disposition du tableau HTML Disposition du tableau HTML Sep 04, 2024 pm 04:54 PM

Guide de mise en page des tableaux HTML. Nous discutons ici des valeurs de la mise en page des tableaux HTML ainsi que des exemples et des résultats en détail.

Déplacer du texte en HTML Déplacer du texte en HTML Sep 04, 2024 pm 04:45 PM

Guide pour déplacer du texte en HTML. Nous discutons ici d'une introduction, du fonctionnement des balises de sélection avec la syntaxe et des exemples à implémenter.

Liste ordonnée HTML Liste ordonnée HTML Sep 04, 2024 pm 04:43 PM

Guide de la liste ordonnée HTML. Ici, nous discutons également de l'introduction de la liste et des types HTML ordonnés ainsi que de leur exemple respectivement.

Comment analysez-vous et traitez-vous HTML / XML dans PHP? Comment analysez-vous et traitez-vous HTML / XML dans PHP? Feb 07, 2025 am 11:57 AM

Ce tutoriel montre comment traiter efficacement les documents XML à l'aide de PHP. XML (Language de balisage extensible) est un langage de balisage basé sur le texte polyvalent conçu à la fois pour la lisibilité humaine et l'analyse de la machine. Il est couramment utilisé pour le stockage de données et

Bouton HTML onclick Bouton HTML onclick Sep 04, 2024 pm 04:49 PM

Guide du bouton HTML onclick. Nous discutons ici de leur introduction, de leur fonctionnement, des exemples et de l'événement onclick dans divers événements respectivement.

See all articles