Récemment, parce que le projet nécessitait de personnaliser une fonction de barrage, j'ai essayé d'utiliser Canvas pour développer des composants. Après des tests sur certaines machines bas de gamme, il n'y a pas de décalage évident. Permettez-moi de partager avec vous.
Effet de barrage Présentation de la fonctionutiliser
npm i vue-barrage
Configuration des paramètres
nom | taper | défaut | desc |
---|---|---|---|
Liste des barrières | Tableau | [] | Données de barrage |
vitesse | Nombre | 4 | Vitesse de défilement du barrage |
boucle | Booléen | vrai | S'il faut faire défiler en boucle |
chaînes | Nombre | 2 | Nombre de voies de barrage |
style HTML
<template> <div class=barrage-container> <div class=container :style={height: barrageHeight/2+'px'}> <canvas id=canvas ref=canvas :width=barrageWidth :height=barrageHeight :style= {'width': barrageWidth/2 + 'px','height': barrièreHeight/2 + 'px'}/> </div> </div></template>implémentation js
Écouter les sources de données
watch: { barrageList (val) { if (val.length !== 0) { this.initData() // Initialisation des données this.render() // Démarrer le rendu} }}
Initialisation des données
barrageArray
est utilisé pour stocker les données de barrage, y compris la liste de barrage par défaut et les nouveaux éléments de barrage.
/** * Initialisation des données*/initData () { for (let i = 0; i < this.barrageList.length; i++) { // Seuls 40 caractères sont affichés ici let content = this.barrageList[i]. longueur > 40 ? `${this.barrageList[i].content.substring(0, 40)}...` : this.barrageList[i].content this.pushMessage(content, this.barrageList[i].color) }},/** * Ajouter des données* @param content * @param color */pushMessage (content, color) { let position = this.getPosition() / / Déterminer la position de la piste let x = this.barrageWidth // Position initiale let offsetWidth = 0 for (let i = 0, len = this.barrageArray.length; i < len; i++) { let item = this.barrageArray[i] if (position === item.position) { // S'ils sont sur la même piste, passez à l'arrière offsetWidth += Math.floor(this.ctx.measureText( item.content) .width * 3 + 60) } } this.barrageArray.push({ content: content, // Contenu du barrage x: x + offsetWidth, // Déterminer la position initiale de chaque commentaire originX : x + offsetWidth, // Stocke la position actuelle du commentaire afin qu'il puisse être utilisé lors de la boucle position : position, width : this.ctx.measureText(content).width * 3, / / Couleur de la largeur du contenu du dessin sur toile : color || this.getColor() // Couleur personnalisée})},
Ce qui doit être traité dans les données d'initialisation, c'est calculer la trace, la position et la largeur du barrage actuel afin qu'il puisse être utilisé lors du dessin canvas
.
Dessiner canvas
/** * Render*/render () { this.ctx.clearRect(0, 0, this.barrageWidth, this.barrageHeight) this.ctx.font = '30px Microsoft YaHei' this.draw() window.requestAnimationFrame(this .render) // Rendu toutes les 16,6 millisecondes si vous utilisez setInterval, ce sera un peu lent sur les modèles bas de gamme},/** *. Commencez à dessiner le texte et l'arrière-plan*/draw () { for (let i = 0, len = this.barrageArray.length; i < len; i++) { let barrage = this.barrageArray[i] try { barrage.x -= this .speed if (barrage.x < -barrage.width - 100) { // Déterminez ici l'heure à laquelle le barrage disparaît if (i === this.barrageArray.length - 1) { // Logique de jugement lorsque le dernier barrage disparaît if (!this.loop) { // Si ce n'est pas une boucle, annulez le dessin pour déterminer s'il s'agit d'une boucle et exécutez CancelAnimationFrame sans boucle CancelAnimationFrame(this.render) return } if (this.addArray .length !== 0) { // Déterminer la logique d'ajout d'un barrage ici this.barrageArray = this.barrageArray.concat(this.addArray) this.addArray = [] } for (let j = 0; j < this.barrageArray.length; j++) { // Donner à chaque barrage une valeur initiale de x this.barrageArray[j].x = this.barrageArray[j].originX } } } if (barrage. x <= 2 * document.body.clientWidth + barrage.width) { // Déterminez quand commencer à dessiner. Sinon, le défilement du barrage sera bloqué //. Dessinez l'arrière-plan this.drawRoundRect(this.ctx, barrage.x - 15, barrage.position - 30, barrage.width + 30, 40, 20, `rgba(0,0,0,0.75)`) // Dessinez l'arrière-plan envoyez ce texte .ctx.fillStyle = `${barrage.color}` this.ctx.fillText(barrage.content, barrage.x, barrage.position) } } catch (e) { console.log(e) } }},
La logique du tirage est jugée ici, y compris le moment d'annuler, le moment où le barrage commence à se dessiner et le moment où le barrage disparaît.
Autres fonctions
/** * Obtenez la position du texte * Utilisez pathWayIndex pour confirmer la piste où se trouve chaque barrage * Renvoie la distance depuis le haut * @TODO Cela peut également être optimisé pour déterminer l'emplacement du prochain barrage en fonction de la distance de chaque piste */ getPosition () { let range = this.channels let top = (this.pathWayIndex % range) * 50 + 40 this.pathWayIndex++ return top},/** * Obtenez une couleur aléatoire*/getColor () { return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);},/** * Dessinez un rectangle arrondi* @ param contexte * @param x * @param y * @param width * @param height * @param radius * @param color */drawRoundRect (context, x, y, largeur, hauteur, rayon, couleur) { context.beginPath() context.fillStyle = color context.arc(x + rayon, y + rayon, rayon, Math.PI, Math.PI * 3/2) context.lineTo (largeur - rayon + x, y) contexte.arc(largeur - rayon + x, rayon + y, rayon, Math.PI * 3/2, Math.PI * 2) contexte.lineTo(largeur + x, hauteur + y - rayon) contexte.arc(largeur - rayon + x, hauteur - rayon + y, rayon, 0, Math.PI / 2) contexte.lineTo(rayon + x, hauteur + y) contexte.arc (rayon + x, hauteur - rayon + y, rayon, Math.PI / 2, Math.PI) context.fill() context.closePath()}
Voici la fonction de service de barrage
utiliser
<barrage ref=barrage class=barrage :barrage-list=barrageList :speed=speed :loop=loop :channels=channels/> import Barrage from 'vue-barrage'// Initialisation des données de barrage this.barrageList = [{ content: ' Données de test numéro de test numéro de données de test données de test', couleur : 'blanc'}]// Ajouter un nouveau barrage this.$refs.barrage.add({ content : 'Ajouter un nouveau barrageAjouter un nouveau barrage', couleur : 'blanc'})Conclusion
Dans l’ensemble, ce composant peut encore être optimisé et je continuerai à l’améliorer à l’avenir.
Ce qui précède représente l’intégralité du contenu de cet article. J’espère qu’il sera utile à l’étude de chacun. J’espère également que tout le monde soutiendra le réseau VeVb Wulin.