Нет лучшего, есть только лучшее. Как видно из названия, в этой статье рассказывается только об эффекте движения частиц, достигнутом с помощью Canvas. Это похоже на заголовок, но с другой точки зрения его вряд ли можно назвать ослепительным. Хотя цвет не имеет ничего общего с ослеплением, эффект движения все равно немного ослепляет. В любом случае, давайте приступим к этому так называемому ослепительному эффекту!
Перейдите непосредственно к коду. Если вы не понимаете, вы можете прочитать комментарии к коду. Вы, вероятно, поймете общую идею.
HTML-код
<!DOCTYPE html><html lang=en><head><meta charset=UTF-8><title>В Canvas достигаются потрясающие эффекты движения частиц — интерфейс облачной библиотеки</title><style>* {margin: 0; : 0;}html,body {ширина: 100%; высота: 100%;}canvas {display: блок; фон: #000;}body::-webkit-scrollbar{ дисплей: нет;}.operator-box{ позиция: фиксированная; сверху: 0; слева: 50%; граница: 1 пиксель сплошной #fff; фон: rgba(255,255,255,0.5); заполнение: 20 пикселей -webkit-transform: TranslateX; (-50%); преобразование: TranslateX(-50%);}.back-type,.back-animate{margin-right: 20px;}.flex-box{ display: flex; justify-content: center; align-items: center;}#input-text{ line-height: 35px; height: 35px; background: rgba(0, 0, 0,0.7); цвет: #fff; размер шрифта: 16 пикселей; граница: нет; 12px; box-shadow: inset 0 0 12px 1px rgba(0,0,0,0.7);}#input-text::placeholder{ color: #ccc; line-height: 55px; height: 55px;}select{ - внешний вид webkit: нет; -moz-внешний вид: нет; граница: нет; отступ: 0 пикселей 20 пикселей; 0 пикселей 6 пикселей; высота: 35 пикселей; цвет: #fff; выравнивание текста: по левому краю; фон: rgba (0, 0, 0,0.7) url(data:image/png;base64,iVBORw0KGgoAAAAANSUhEUgAAAAUAAAAICAYAAAAx8TU7AAAAOUlEQ…R4gPgWEIMAiOYBCS4C8ZDAIrBq4gigNkztQEFMi6AuQHESAPMeXiEMiWfpAAAAAElFTkSuQmCC) без повтора 190 пикселей 12px; размер фона: 5 пикселей 8 пикселей; box-shadow: inset 0 0 12px 1px rgba(0,0,0,0.7);</style></head><body><div class=operator-box>< div class=flex-box> <div class=back-type>Тип разворота: <select name= id=selectType> <option value=back>Return</option> <option value=auto>Random</option> </select> </div> <div class=back-animate>Эффект дисперсии (эффективен для возврата в исходное положение): <select class=back-dynamics id=selectDynamics> <option value= Spring>dynamics.spring</option> <option value=bounce>dynamics.bounce</option> <option value=forceWithGravity>dynamics.forceWithGravity</option> <option value=gravity>dynamics.gradity</option> <option value=easeInOut>dynamics.easeInOut</option> <option value=easeIn>dynamics.easeIn</option> <option value=easeOut>dynamics.easeOut</ option> <option value=linear>dynamics.linear</option> </select> </div> <div class=input-box><input type=text Placeholder=Введите китайские символы и нажмите Enter id=input-text></div></div></div><script src=dynamics.min.js></script><script src=index.js></ script ><script>var iCircle = new Circle();</script></body></html>
Здесь не так много HTML-кода, всего несколько рабочих элементов. Здесь легко понять с первого взгляда. Не нужно тратить слишком много слов. Давайте взглянем на главный JavaScript-код этой статьи. Однако, прежде чем рассматривать код, мы могли бы также прислушаться к идее достижения этого эффекта:
В коде JavaScript используются три холста Canvas: this.iCanvas (домашняя страница), this.iCanvasCalculate (используется для расчета ширины текста), this.iCanvasPixel (используется для рисования текста и получения координат положения пикселей, соответствующих тексту). ) .
this.iCanvasCalculate и this.iCanvasPixel не обязательно должны отображаться на странице, это всего лишь вспомогательные функции.
Вот потрясающий код реализации JS
function Circle() { var This = this; this.init(); this.drawCircles(); this.getUserText(); // После изменения размера окна и Получить экран window.onresize = function(){ This.stateW = document.body.offsetWidth This.stateH = document.body.offsetHeight; This.iCanvasW = This.iCanvas.width = This.stateW; This.iCanvasH = This.iCanvas.height = This.stateH; This.ctx = This.iCanvas.getContext(2d); }}//Инициализировать Circle.prototype.init = function( ){ //Ширина и высота родительского элемента this.stateW = document.body.offsetWidth; this.stateH = document.body.offsetHeight this.iCanvas = document.createElement(canvas); // Установите для Canvas ту же ширину и высоту, что и у родительского элемента this.iCanvasW = this.iCanvas.width = this.stateW; this.iCanvasH = this.iCanvas.height = this.stateH; // Получение 2D-среды рисования this.ctx = this.iCanvas.getContext(2d); // Вставка в элемент тела document.body.appendChild(this.iCanvas); this.iCanvasCalculate = document.createElement(canvas); // Холст, используемый для сохранения рассчитанной ширины текста this.mCtx = this.iCanvasCalculate.getContext(2d); this.mCtx.font = 128px Microsoft Yahei; this.iCanvasPixel = document .createElement (холст); this.iCanvasPixel.setAttribute(style,position:absolute;top:0;left:0;); this.pCtx = null; // Холст, используемый для рисования текста // Количество случайно сгенерированных кругов this.ballNumber = ramdomNumber(1000) , 2000); // Сохраняем массив всех шариков this.balls = [] // Сохраняем последний шарик, который остановился в анимации this.animte = null; this.imageData = null; this.textWidth = 0; // Сохраняем ширину сгенерированного текста this.textHeight = 150 // Сохраняем высоту сгенерированного текста this.inputText = // Сохраняем содержимое, введенное пользователем. this.actionCount = 0; this.ballActor = []; // Сохраняем частицы, генерирующие текст this.actorNumber = 0 // Сохраняем количество частиц, генерирующих текст this.backType = back; ; // Эффект анимации this.isPlay = false; // Логотип (невозможно сгенерировать во время генерации текста)}// Отображение всех кругов Circle.prototype.drawCircles = function () { for(var i=0;i <this.ballNumber ;i++){ this.renderBall(this.balls[0]); // Получаем вводимый пользователем текст Circle.prototype.getUserText = function(){ This = this; // Сохраните это, чтобы указать на ipu = document.getElementById(input-text); ipu.addEventListener(keydown,function(event){ if(event.that === 13){ // Если это клавиша ввода ipu.value = ipu.value.trim(); // Удалить начальные и конечные пробелы var pat = /[/u4e00-/u9fa5]/ // Китайское решение var isChinese =; pat.test(ipu.value); if(ipu.value.length !=0 && isChinese){ This.inputText = ipu.value; }else{ alert(Введите китайские символы return; } if(This.isPlay); ) { return } This.getAnimateType(); This.getTextPixel(); This.isPlay = true; Вычисляем ширину текста Circle.prototype.calculateTextWidth = function () { this.textWidth = this.mCtx.measureText(this.inputText).width;}// Получаем пиксели текста Circle.prototype.getTextPixel = function () { если( this.pCtx){ this.pCtx.clearRect(0,0,this.textWidth,this.textHeight); } this.calculateTextWidth(this.inputText); this.iCanvasPixel.width = this.textWidth; this.iCanvasPixel.height = this.textHeight; .pCtx = this.iCanvasPixel.getContext(2d); this.pCtx.font = 128 пикселей Microsoft Yahei; this.pCtx.fillStyle = #FF0000; this.pCtx.textBaseline = botom; 0,0,this.textWidth,this.textHeight).data; this.getTextPixelPosition(this.textWidth,this.textHeight);}//Получаем положение частицы текста в пикселях Circle.prototype.getTextPixelPosition = function (width,height) { var left = (this.iCanvasW - width)/2; = (this.iCanvasH - высота)/2 var space = 4; this.actionCount = 0; i=0;i<this.textHeight;i+=space){ for(var j=0;j<this.textWidth;j+=space){ var index = j*space+i*this.textWidth*4; this.imageData[index] == 255){ if(this.actionCount<this.ballNumber){ this.balls[this.actionCount].status = 1; this.balls[this.actionCount].targetX = left+j; this.balls[this.actionCount].targetY = top+i; this.balls[this.actionCount].backX = this.balls[this.actionCount]. x; this.balls[this.actionCount].backY = this.balls[this.actionCount].y; this.ballActor.push(this.balls[this.actionCount]); } } } this.actorNumber = this.ballActor.length; } this.animateToText();}//Частица перемещается в указанную позицию Circle.prototype.animateToText = function(){ for(var i=0;i<This .actorNumber ;i++){dynamic.animate(This.ballActor[i], { x: this.ballActor[i].targetX, y: this.ballActor[i].targetY },{ type:dynamic.easeIn, period: 1024, }); setTimeout(function(){ This.ballbackType(); },3000);}//Частицы возвращаются в исходное состояние. Обведите круг по исходному пути .prototype.ballBackPosition = function(){ for(var i=0;i<This.actorNumber;i++){ var ball = This.ballActor[i];dynamic.animate(ball, { x: ball.backX, y: ball.backY }, { type:dynamics[this.backDynamics], продолжительность: 991, Complete:this.changeStatus(ball) } }}// Получить тип|эффект анимации Circle.prototype.getAnimateType = function() { var selectType = document.getElementById(selectType); var selectDynamics = document.getElementById(selectDynamics); this.backType = selectType.options[selectType.options.selectedIndex].value; this.backDynamics = selectDynamics.options[selectDynamics.options.selectedIndex].value;}//Сбросить круг распространения .prototype.ballbackType = function(){ if(this.backType == назад){ this.ballBackPosition(); }else{ this.ballAutoPosition(); } this.ballActor = [];}// Случайно разбрасываем Circle.prototype.ballAutoPosition = function(ball){ for(var i= 0 ;i<this.actorNumber;i++){ this.changeStatus(this.ballActor[i]) }}// Изменить статус мяча Circle.prototype.changeStatus = function(ball){ ball.status = 0; if(this.isPlay == true){ this.isPlay = false }}// Генерировать случайным образом соответствующие параметры каждого круга Circle. .prototype.generalRandomParam = function(){ for(var i=0;i<this.ballNumber;i++){ var ball = {}; Случайно сгенерировать радиус круга // Случайно сгенерировать координату центра x круга ball.x = ramdomNumber(0+ball.size, this.iCanvasW-ball.size ball.y = ramdomNumber(0+ball.size, this.iCanvasH-ball); . size); ball.speedX = ramdomNumber(-1, 1); ball.speedY = ramdomNumber(-1, 1); ball.status = 0; ball.targetX = 0; ball.backX = 0; ball.backY = 0; // Изменить положение круга Circle.prototype.changeposition = function(){ for( var i=0;i<this.ballNumber;i++){ if( this.balls[i].status == 0){ this.balls[i].x += this.balls[i].speedX; this.balls[i].y += this.balls[i].speedY } }}// Рисуем круг Circle.prototype.renderBall = function(ball){ this.ctx; . fillStyle = #fff; this.ctx.beginPath(); // Это необходимо добавить с помощью this.ctx.arc(ball.x, ball.y, ball.size, 0, 2 * Math.PI); this.ctx.closePath(); // Это необходимо добавить с помощью this.ctx.fill();}// Решение о столкновении мяча Circle.prototype.collision = function(ball){ for(var i= 0;i<this.ballNumber;i++){ if(ball.x>this.iCanvasW-ball.size || ball.x<ball.size){ if(ball.x>this.iCanvasW-ball.size){ ball.x = this.iCanvasW-ball.size; }else{ ball.x = ball.size; } ball.speedX = - ball.speedX } if(ball.x>this.iCanvasW-ball.size){ ball.x = this.iCanvasW-ball.size; (ball.y>this.iCanvasH-ball.size || ball.y<ball.size){ if(ball.y>this.iCanvasH-ball.size){ ball.y = this.iCanvasH-ball.size; }else{ ball.y = ball.size; } ball.speedY = - ball.speedY } }}// Запустить анимацию Circle.prototype.ballAnimate = function(){ var This = this ; var animateFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; (функция move(){ animte = animateFrame(move); This.ctx.clearRect(0, 0, This.iCanvasW, This.iCanvasH); This.changeposition(); for(var i=0;i <This.ballNumber;i++){ This.collision(This.balls[i]); This.renderBall(This.balls[i]); })();}//Сгенерируем случайное число function ramdomNumber(min, max) { return Math.random() * (max - min) + min;}
После прочтения кода я думаю, это был всего лишь небольшой понт, и это не вызвало у вас желания сделать эту штуку. Для этого, я знаю, вас нужно убедить глазами и ртом. Онлайн-ДЕМО: Пример динамических частиц.
Никто не идеален, и код тоже. Код, который, кажется, работает гладко, имеет те или иные недостатки. В настоящее время этот эффект поддерживает только китайский язык. Что касается английского, то мне придется больше работать. Несмотря ни на что, английский обязательно присоединится позже, это лишь вопрос времени. В коде также есть атрибут, указывающий, может ли сгенерированный текст быть выполнен снова: this.isPlay, что все еще является небольшим недостатком. Изменение состояния this.isPlay не меняется точно в тот момент, когда частицы возвращаются. но заранее меняет состояние. Но это состояние не повлияет на полную реализацию эффекта этого примера.
В этом примере используется библиотекаdynamic.js, главным образом, для использования в ней некоторых функций движения, чтобы сделать движение частиц более впечатляющим, вот и все.
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.