Recentemente, como o projeto precisava customizar uma função de barragem, tentei usar o canvas para desenvolver componentes. Depois de testar em algumas máquinas de baixo custo, não há atraso óbvio.
Efeito barragem Introdução à funçãousar
npm i vue-barrage
Configuração de parâmetros
nome | tipo | padrão | desc |
---|---|---|---|
lista de barreiras | Variedade | [] | Dados de barragem |
velocidade | Número | 4 | Velocidade de rolagem da barragem |
laço | Booleano | verdadeiro | Se deve rolar em loop |
canais | Número | 2 | Número de trilhas de barragem |
estilo html
<template> <div class=barrage-container> <div class=container :style={height: barrageHeight/2+'px'}> <canvas id=canvas ref=canvas :width=barrageWidth :height=barrageHeight :style= {'largura': barrageWidth/2 + 'px','altura': barreiraHeight/2 + 'px'}/> </div> </div></template>implementação js
Ouça as fontes de dados
watch: { barrageList (val) { if (val.length !== 0) { this.initData() // Inicialização dos dados this.render() // Inicia a renderização} }}
Inicialização de dados
barrageArray
é usado para armazenar dados de barragem, incluindo a lista de barragens padrão e novos itens de barragens.
/** * Inicialização de dados*/initData () { for (let i = 0; i < this.barrageList.length; i++) { // Apenas 40 caracteres são exibidos aqui let content = this.barrageList[i]. comprimento > 40 ? `${this.barrageList[i].content.substring(0, 40)}...` : this.barrageList[i].content this.pushMessage(content, this.barrageList[i].color) }},/** * Adicionar dados* @param content * @param color */pushMessage (content, color) { let position = this.getPosition() / / Determine a posição da pista let x = this.barrageWidth // Posição inicial let offsetWidth = 0 for (let i = 0, len = this.barrageArray.length; i < len; i++) { let item = this.barrageArray[i] if (position === item.position) { // Se eles estiverem na mesma trilha, vá para trás offsetWidth += Math.floor(this.ctx.measureText( item.content) .width * 3 + 60) } } this.barrageArray.push({ content: content, // Conteúdo da barragem x: x + offsetWidth, // Determine a posição inicial de cada comentário originX: x + offsetWidth, // Armazene a posição atual do comentário para que possa ser usado durante o loop position: position, width: this.ctx.measureText(content).width * 3, / / Largura do conteúdo do desenho da tela color: color || this.getColor() // Cor personalizada})},
O que precisa ser processado nos dados de inicialização é calcular o trajeto, posição e largura da barragem atual para que possa ser usada no desenho canvas
.
Desenhar canvas
/** * Render*/render () { this.ctx.clearRect(0, 0, this.barrageWidth, this.barrageHeight) this.ctx.font = '30px Microsoft YaHei' this.draw() window.requestAnimationFrame(this .render) // Renderiza a cada 16,6 milissegundos Se você usar setInterval, será um pouco lento em modelos de baixo custo},/** *. Comece a desenhar texto e plano de fundo*/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) { // Determine o tempo em que a barragem desaparece aqui if (i === this.barrageArray.length - 1) { // Lógica de julgamento quando a última barragem desaparece if (!this.loop) { // Se não for um loop, cancele o desenho para determinar se é um loop e execute cancelAnimationFrame sem loop cancelAnimationFrame(this.render) return } if (this.addArray .length !== 0) { // Determine a lógica de adição de barragem aqui this.barrageArray = this.barrageArray.concat(this.addArray) this.addArray = [] } for (deixe j = 0; j < this.barrageArray.length; j++) { // Dê a cada barragem um valor inicial de x this.barrageArray[j].x = this.barrageArray[j].originX } } } if (barrage. x <= 2 * document.body.clientWidth + barrage.width) { // Determine quando começar a desenhar, caso contrário, a rolagem da barragem travará //. Desenhe o plano de fundo this.drawRoundRect(this.ctx, barrage.x - 15, barrage.position - 30, barrage.width + 30, 40, 20, `rgba(0,0,0,0.75)`) // Desenhe o envie uma mensagem de texto para isto .ctx.fillStyle = `${barrage.color}` this.ctx.fillText(barrage.content, barrage.x, barrage.position) } } catch (e) { console.log(e) } }},
A lógica de desenho é julgada aqui, incluindo quando cancelar, julgar quando a barragem começa a puxar e julgar quando a barragem desaparece.
Outras funções
/** * Obtém a posição do texto * Use pathWayIndex para confirmar a trilha onde cada barragem está localizada * Retorna a distância do topo * @TODO Isso também pode ser otimizado para determinar a localização da próxima barragem com base na distância de cada trilha */ getPosition () { let range = this.channels let top = (this.pathWayIndex % range) * 50 + 40 this.pathWayIndex++ return top},/** * Obtenha uma cor aleatória*/getColor () { return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);},/** * Desenha um retângulo arredondado* @ param contexto * @param x * @param y * @param largura * @param altura * @param raio * @param cor */drawRoundRect (contexto, x, y, largura, altura, raio, cor) { context.beginPath() context.fillStyle = color context.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3/2) context.lineTo (largura - raio + x, y) context.arc (largura - raio + x, raio + y, raio, Math.PI * 3/2, Math.PI * 2) context.lineTo (largura + x, altura + y - raio) context.arc(largura - raio + x, altura - raio + y, raio, 0, Math.PI / 2) context.lineTo(raio + x, altura + y) context.arc (raio + x, altura - raio + y, raio, Math.PI / 2, Math.PI) context.fill() context.closePath()}
Aqui está a função de serviço de barragem
usar
<barrage ref=barrage class=barrage :barrage-list=barrageList :speed=speed :loop=loop :channels=channels/> importar Barrage from 'vue-barrage'// Inicialização de dados de barragem this.barrageList = [{ content: ' Dados de teste número de teste número de dados de teste dados de teste', color: 'white'}]// Adicionar nova barragem this.$refs.barrage.add({ content: 'Adicionar uma nova barragemAdicionar uma nova barragem', cor: 'branco'})Conclusão
No geral, este componente ainda tem espaço para otimização e continuarei a melhorá-lo no futuro.
O texto acima é todo o conteúdo deste artigo. Espero que seja útil para o estudo de todos. Também espero que todos apoiem a Rede VeVb Wulin.