Недавно, поскольку в проекте нужно было настроить функцию заграждения, я попытался использовать Canvas для разработки компонентов. После тестирования на некоторых младших машинах явных задержек не обнаружено. Позвольте мне поделиться с вами.
Эффект заградительного огня Введение функциииспользовать
npm i vue-barrage
Конфигурация параметров
имя | тип | по умолчанию | описание |
---|---|---|---|
барьерСписок | Множество | [] | Данные о заграждении |
скорость | Число | 4 | Скорость прокрутки заградительного огня |
петля | логическое значение | истинный | Прокручивать ли в цикле |
каналы | Число | 2 | Количество заградительных траков |
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': BarrageHeight/2 + 'px'}/> </div> </div></template>js-реализация
Слушайте источники данных
watch: { barrageList (val) { if (val.length !== 0) { this.initData() // Инициализация данных this.render() // Начинаем рендеринг} }}
Инициализация данных
barrageArray
используется для хранения данных заграждения, включая список заграждений по умолчанию и новые элементы заграждения.
/** * Инициализация данных*/initData () { for (let i = 0; i < this.barrageList.length; i++) { // Здесь отображается только 40 символов let content = this.barrageList[i content]. длина > 40 ? `${this.barrageList[i].content.substring(0, 40)}...` : this.barrageList[i].content this.pushMessage(content, this.barrageList[i].color) }},/** * Добавить данные* @param content * @param color */pushMessage (content, color) { let Position = this.getPosition() / / Определить положение взлетно-посадочной полосы let x = this.barrageWidth // Исходное положение let offsetWidth = 0 for (let i = 0, len = this.barrageArray.length; i < len; i++) { let item = this.barrageArray[i] if (position === item.position) { // Если они находятся на одной дорожке, переходим назад offsetWidth += Math.floor(this.ctx.measureText( item.content) .width * 3 + 60) } } this.barrageArray.push({ content: content, // Заграждение содержимого x: x + offsetWidth, // Определить начальную позицию каждого комментария originX: x + offsetWidth, // Сохраняем текущую позицию комментария, чтобы ее можно было использовать во время цикла. / Цвет ширины содержимого рисунка холста: color || this.getColor() // Пользовательский цвет})},
Что необходимо обработать в данных инициализации, так это вычислить путь, положение и ширину текущего заграждения, чтобы их можно было использовать при отрисовке canvas
.
Нарисовать canvas
/** * Render*/render () { this.ctx.clearRect(0, 0, this.barrageWidth, this.barrageHeight) this.ctx.font = '30px Microsoft YaHei' this.draw() window.requestAnimationFrame(this .render) // Рендеринг каждые 16,6 миллисекунды. Если вы используете setInterval, на младших моделях он будет немного запаздывать},/** *. Начать рисовать текст и фон*/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) { // Здесь определяем время, когда заграждение исчезнет if (i === this.barrageArray.length - 1) { // Логика принятия решения, когда последний заграждение исчезает if (!this.loop) { // Если это не цикл, отмените рисование, чтобы определить, является ли это циклом, и выполните cancelAnimationFrame без цикла cancelAnimationFrame(this.render) return } if (this.addArray .length !== 0) { // Здесь определяем логику добавления заграждения this.barrageArray = this.barrageArray.concat(this.addArray) this.addArray = [] } for (let j = 0; j < this.barrageArray.length; j++) { // Даем каждому заграждению начальное значение x this.barrageArray[j].x = this.barrageArray[j].originX } } } if (barrage. x <= 2 * document.body.clientWidth + barrage.width) { // Определяем, когда начинать рисование. Если нет, это приведет к зависанию прокрутки // Рисуем фон this.drawRoundRect(this.ctx, barrage.x - 15, barrage.position - 30, barrage.width + 30, 40, 20, `rgba(0,0,0,0.75)`) // Рисуем фон отправьте текст this .ctx.fillStyle = `${barrage.color}` this.ctx.fillText(barrage.content, barrage.x, barrage.position) } } catch (e) { console.log(e) } }},
Здесь оценивается логика рисования, в том числе, когда следует отменить, когда начинается рисование заграждения и когда заграждение исчезает.
Другие функции
/** * Получить позицию текста * Используйте pathWayIndex для подтверждения пути, на котором расположен каждый заграждение * Возвращает расстояние сверху * @TODO Это также можно оптимизировать для определения местоположения следующего заграждения на основе расстояния каждого пути */ getPosition () { let range = this.channels let top = (this.pathWayIndex % range) * 50 + 40 this.pathWayIndex++ return top},/** * Получить случайный цвет*/getColor () { return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);},/** * Нарисуйте прямоугольник с закругленными углами* @ контекст параметра * @param x * @param y * @param width * @param height * @param radius * @param color */drawRoundRect (context, x, y, ширина, высота, радиус, цвет) { context.beginPath() context.fillStyle = цвет context.arc(x + радиус, y + радиус, радиус, Math.PI, Math.PI * 3/2) context.lineTo (ширина - радиус + x, y) context.arc(ширина - радиус + x, радиус + y, радиус, Math.PI * 3/2, Math.PI * 2) context.lineTo(ширина + x, высота + y - радиус) context.arc(ширина - радиус + x, высота - радиус + y, радиус, 0, Math.PI/2) context.lineTo(радиус + x, высота + y) context.arc (радиус + x, высота – радиус + y, радиус, Math.PI/2, Math.PI) context.fill() context.closePath()}
Вот функция службы заграждения
использовать
<barrage ref=barrage class=barrage :barrage-list=barrageList :speed=speed :loop=loop :channels=channels/> import Barrage from 'vue-barrage'// Инициализация данных Barrage this.barrageList = [{ content: ' Тестовые данные, номер теста, номер тестовых данных, тестовые данные', цвет: 'white'}]// Добавить новый заграждение this.$refs.barrage.add({ content: 'Добавить новый заграждениеДобавить новый заграждение', цвет: 'белый'})Заключение
В целом, этому компоненту еще есть куда оптимизировать, и я продолжу его улучшать в будущем.
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.