Recientemente, debido a que el proyecto necesitaba personalizar una función de bombardeo, intenté usar lienzo para desarrollar componentes. Después de realizar pruebas en algunas máquinas de gama baja, no hay ningún retraso evidente. Permítanme compartirlo con ustedes.
efecto bombardeo Introducción a la funciónusar
npm i vue-barrage
Configuración de parámetros
nombre | tipo | por defecto | desc |
---|---|---|---|
Lista de barreras | Formación | [] | Datos de bombardeo |
velocidad | Número | 4 | Velocidad de desplazamiento del bombardeo |
bucle | booleano | verdadero | Ya sea para desplazarse en un bucle |
canales | Número | 2 | Número de vías de bombardeo |
estilo html
<plantilla> <div class=barrage-container> <div class=container :style={height: barrageHeight/2+'px'}> <canvas id=canvas ref=canvas :width=barrageWidth :height=barrageHeight :style= {'ancho': barrageWidth/2 + 'px','altura': barreraHeight/2 + 'px'}/> </div> </div></template>implementación js
Escuche fuentes de datos
reloj: { barrageList (val) { if (val.length! == 0) { this.initData() // Inicialización de datos this.render() // Iniciar renderizado} }}
Inicialización de datos
barrageArray
se utiliza para almacenar datos de bombardeo, incluida la lista de bombardeo predeterminada y nuevos elementos de bombardeo.
/** * Inicialización de datos*/initData () { for (let i = 0; i < this.barrageList.length; i++) { // Aquí solo se muestran 40 caracteres let content = this.barrageList[i]. longitud> 40? `${this.barrageList[i].content.substring(0, 40)}....`: this.barrageList[i].content this.pushMessage(content, this.barrageList[i].color) }},/** * Agregar datos* @param content * @param color */pushMessage (content, color) { let position = this.getPosition() / / Determinar la posición de la pista let x = this.barrageWidth // Posición inicial let offsetWidth = 0 for (let i = 0, len = this.barrageArray.length; i < len; i++) { let item = this.barrageArray[i] if (position === item.position) { // Si están en la misma pista, muévete hacia atrás offsetWidth += Math.floor(this.ctx.measureText( item.content) .width * 3 + 60) } } this.barrageArray.push({ contenido: contenido, // Contenido de bombardeo x: x + offsetWidth, // Determine la posición inicial de cada comentario originX: x + offsetWidth, // Almacene la posición actual del comentario para que pueda usarse durante el bucle position: position, width: this.ctx.measureText(content).width * 3, / / Color del ancho del contenido del dibujo del lienzo: color || this.getColor() // Color personalizado})},
Lo que debe procesarse en los datos de inicialización es calcular la ruta, la posición y el ancho del bombardeo actual para que pueda usarse al dibujar canvas
.
Dibujar 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 cada 16,6 milisegundos Si usa setInterval, será un poco lento en modelos de gama baja},/** *. Comience a dibujar texto y fondo*/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) { // Determina el momento en que el bombardeo desaparece aquí if (i === this.barrageArray.length - 1) { // Lógica de juicio cuando desaparece el último bombardeo if (!this.loop) { // Si no es un bucle, cancele el dibujo para determinar si es un bucle y ejecute cancelAnimationFrame sin bucle cancelAnimationFrame(this.render) return } if (this.addArray .length !== 0) { // Determinar la lógica de agregar bombardeo aquí this.barrageArray = this.barrageArray.concat(this.addArray) this.addArray = [] } for (let j = 0; j < this.barrageArray.length; j++) { // Da a cada bombardeo un valor inicial de x this.barrageArray[j].x = this.barrageArray[j].originX } } } if (barrage. x <= 2 * document.body.clientWidth + barrage.width) { // Determina cuándo comenzar a dibujar. De lo contrario, el desplazamiento del bombardeo se atascará. Dibuja el fondo this.drawRoundRect(this.ctx, barrage.x - 15, barrage.position - 30, barrage.width + 30, 40, 20, `rgba(0,0,0,0.75)`) // Dibuja el envía un mensaje de texto con este .ctx.fillStyle = `${barrage.color}` this.ctx.fillText(barrage.content, barrage.x, barrage.position) } } catch (e) { console.log(e) } }},
Aquí se juzga la lógica del sorteo, incluido cuándo cancelar, cuándo comienza el bombardeo y cuándo desaparece el bombardeo.
Otras funciones
/** * Obtener la posición del texto * Usar pathWayIndex para confirmar la ruta donde se encuentra cada barrera * Devolver la distancia desde la parte superior * @TODO Esto también se puede optimizar para determinar la ubicación de la siguiente barrera en función de la distancia de cada pista */ getPosition () { let range = this.channels let top = (this.pathWayIndex % rango) * 50 + 40 this.pathWayIndex++ return top},/** * Obtener un color aleatorio*/getColor () { return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);},/** * Dibujar un rectángulo redondeado* @ contexto de parámetro * @param x * @param y * @param ancho * @param alto * @param radio * @param color */drawRoundRect (contexto, x, y, ancho, alto, radio, color) { contexto.beginPath() contexto.fillStyle = color contexto.arc(x + radio, y + radio, radio, Math.PI, Math.PI * 3/2) context.lineTo (ancho - radio + x, y) contexto.arc(ancho - radio + x, radio + y, radio, Math.PI * 3/2, Math.PI * 2) contexto.lineTo(ancho + x, altura + y - radio) contexto.arc(ancho - radio + x, altura - radio + y, radio, 0, Math.PI / 2) contexto.lineTo(radio + x, altura + y) contexto.arc (radio + x, altura - radio + y, radio, Math.PI / 2, Math.PI) context.fill() context.closePath()}
Aquí está la función del servicio de bombardeo.
usar
<barrage ref=barrage class=barrage :barrage-list=barrageList :speed=speed :loop=loop :channels=channels/> importar Barrage desde 'vue-barrage'// Inicialización de datos de Barrage this.barrageList = [{ content: ' Datos de prueba número de prueba número de datos de prueba datos de prueba', color: 'blanco'}]// Agregar nuevo bombardeo this.$refs.barrage.add({ content: 'Agregar un nuevo bombardeoAgregar un nuevo bombardeo', color: 'blanco'})Conclusión
En general, este componente todavía tiene margen de optimización y continuaré mejorándolo en el futuro.
Lo anterior es el contenido completo de este artículo. Espero que sea útil para el estudio de todos. También espero que todos apoyen VeVb Wulin Network.