No hay mejor, solo mejor. Como indica el título, este artículo solo quiere compartir un efecto de movimiento de partículas logrado con Canvas. Parece un título, pero desde otra perspectiva apenas puede considerarse deslumbrante. Aunque el color no tiene nada que ver con el deslumbramiento, el efecto de movimiento sigue siendo un poco deslumbrante. De todos modos, ¡comencemos con este llamado efecto deslumbrante!
Vaya directamente al código. Si no lo comprende, puede leer los comentarios del código. Probablemente entenderás la idea general.
código html
<!DOCTYPE html><html lang=en><head><meta charset=UTF-8><title>Canvas logra deslumbrantes efectos de movimiento de partículas: interfaz de la biblioteca en la nube</title><style>* { margin: 0; : 0;}html,cuerpo { ancho: 100%; alto: 100%;}lienzo { pantalla: bloque; fondo: #000;}cuerpo::-webkit-scrollbar{ mostrar: ninguno;}.operator-box{ posición: fijo; arriba: 0; izquierda: 50%; borde: 1px sólido #fff; (-50%); transformar: traducirX(-50%);}.back-type,.back-animate{ margen-derecho: 20px;}.flex-box{ display: flex; justify-content: center; align-items: center;}#input-text{ altura de línea: 35px; ancho: 260px; 0, 0,0.7); color: #fff; tamaño de fuente: 16px; borde: ninguno; 12px; sombra de cuadro: inserto 0 0 12px 1px rgba(0,0,0,0.7);}#input-text::placeholder{ color: #ccc; altura de línea: 55px;}select{ - apariencia del kit web: ninguna; -apariencia de moz: ninguna; apariencia: ninguna; 0px 6px; altura: 35px; color: #fff; alineación de texto: izquierda; rgba(0, 0, 0,0.7) url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAICAYAAAAx8TU7AAAAOUlEQ…R4gPgWEIMAiOYBCS4C8ZDAirBq4gigNkztQEFMi6AuQHESAPMeXiEMiWfpAAAAAElFTkSuQmCC) sin repetición 190px 12px; tamaño de fondo: 5px 8px; sombra de cuadro: inserción 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>Tipo de extensión: <select name= id=selectType> <option value=back>Return</option> <option value=auto>Random</option> </select> </div> <div class=back-animate>Efecto de dispersión (efectivo para referenciar): <select class=back-dynamics id=selectDynamics> <option value= spring>dynamics.spring</option> <option value=bounce>dynamics.bounce</option> <option value=forceWithGravity>dynamics.forceWithGravity</option> <opción valor=gravedad>dinámica.gravity</opción> <opción valor=easeInOut>dinámica.easeInOut</opción> <opción valor=easeIn>dinámica.easeIn</opción> <opción valor=easeOut>dinámica.easeOut</ opción> <opción valor=lineal>dinámica.lineal</opción> </select> </div> <div clase=input-box><tipo de entrada=texto placeholder=Ingrese caracteres chinos y presione Enter id=input-text></div></div></div><script src=dynamics.min.js></script><script src=index.js></ script ><script>var iCircle = nuevo círculo();</script></body></html>
No hay mucho código HTML, sólo unos pocos elementos operativos. Es fácil de entender de un vistazo aquí. No hay necesidad de desperdiciar demasiadas palabras. Echemos un vistazo al código JavaScript protagonista de este artículo. Sin embargo, antes de mirar el código, también podríamos escuchar la idea de lograr este efecto:
Se utilizan tres lienzos Canvas en el código JavaScript, this.iCanvas (página de inicio), this.iCanvasCalculate (usado para calcular el ancho del texto), this.iCanvasPixel (usado para dibujar texto y obtener las coordenadas de posición de los píxeles correspondientes al texto). ).
No es necesario que this.iCanvasCalculate y this.iCanvasPixel se muestren en la página, son solo funciones auxiliares.
Aquí está el increíble código de implementación JS.
function Circle() { var This = this; this.init(); this.generalRandomParam(); this.drawCircles(); this.ballAnimate(); Obtenga la ventana de pantalla.onresize = function(){ This.stateW = document.body.offsetWidth This.stateH = document.body.offsetHeight; This.iCanvas.width = This.stateW; This.iCanvasH = This.iCanvas.height = This.stateH; This.ctx = This.iCanvas.getContext(2d); ){ // Ancho y alto del elemento principal this.stateW = document.body.offsetWidth; this.stateH = document.body.offsetHeight = this.iCanvas; document.createElement(canvas); // Establece Canvas para que tenga el mismo ancho y alto que el elemento principal this.iCanvasW = this.iCanvas.width = this.stateW; // Obtener entorno de pintura 2d this.ctx = this.iCanvas.getContext(2d); // Insertar en el elemento del cuerpo document.body.appendChild(this.iCanvas); this.iCanvasCalculate = document.createElement(canvas); // Lienzo utilizado para guardar el ancho del texto calculado this.mCtx = this.iCanvasCalculate.getContext(2d); this.mCtx.font = 128px Microsoft Yahei; (lienzo); this.iCanvasPixel.setAttribute(style,position:absolute;top:0;left:0;); this.pCtx = null // Lienzo utilizado para dibujar texto // El número de círculos generados aleatoriamente this.ballNumber = ramdomNumber(1000 , 2000); // Guarda una matriz de todas las bolas this.balls = []; // Guarda la última bola que dejó de moverse en la animación this.animte = null; this.imageData = null; this.textWidth = 0; // Guarda el ancho del texto generado this.textHeight = 150 // Guarda el alto del texto generado this.inputText = // Guarda el contenido ingresado por el usuario. this.actionCount = 0; this.ballActor = []; // Guarda las partículas que generan texto this.actorNumber = 0; // Guarda el número de partículas que generan texto this.backType = back; ; // Efecto de animación this.isPlay = false; // Logotipo (no se puede generar durante la generación de texto)}// Representar todos los círculos Circle.prototype.drawCircles = function () { for(var i=0;i <this.ballNumber ;i++){ this.renderBall(this.balls[0]); }}// Obtener texto ingresado por el usuario Circle.prototype.getUserText = function(){ This = this; // Guarde esto para que apunte a ipu = document.getElementById(input-text); ipu.addEventListener(keydown,function(event){ if(event. Which === 13){ // Si es la tecla Intro ipu.value = ipu.value.trim(); // Elimina los espacios iniciales y finales var pat = /[/u4e00-/u9fa5]/ // Juicio chino var isChinese =; pat.test(ipu.value); if(ipu.value.length!=0 && isChinese){ This.inputText = ipu.value; }else{ alerta(Ingrese caracteres chinos return); ) {retorno} This.getAnimateType(); This.getTextPixel(); This.isPlay = verdadero; Calcular el ancho del texto Circle.prototype.calculateTextWidth = function () { this.textWidth = this.mCtx.measureText(this.inputText).width;}// Obtener los píxeles del texto Circle.prototype.getTextPixel = function () { si(este.pCtx){ this.pCtx.clearRect(0,0,this.textWidth,this.textHeight); } this.calculateTextWidth(this.inputText); this.iCanvasPixel.width = this.textWidth; .pCtx = this.iCanvasPixel.getContext(2d); this.pCtx.font = 128px Microsoft Yahei; this.pCtx.fillStyle = #FF0000; this.pCtx.textBaseline = abajo; this.pCtx.fillText(this.inputText,0,110); 0,0,este.textWidth,this.textHeight).datos; this.getTextPixelPosition(this.textWidth,this.textHeight);}//Obtener la posición del píxel de la partícula de texto Circle.prototype.getTextPixelPosition = function (width,height) { var left = (this.iCanvasW - width)/2; = (this.iCanvasH - altura)/2; var espacio = 4; this.actionCount = 0; i=0;i<this.textHeight;i+=espacio){ for(var j=0;j<this.textWidth;j+=space){ var index = j*espacio+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();}//La partícula se mueve a la posición especificada Circle.prototype.animateToText = function(){ for(var i=0;i<This .actorNumber ;i++){ dinámica.animate(Este.ballActor[i], { x: este.ballActor[i].targetX, y: this.ballActor[i].targetY },{ tipo: dinámica.easeIn, duración: 1024, }); setTimeout(function(){ This.ballbackType(); },3000);}//Las partículas regresan al Círculo a lo largo de la ruta original .prototype.ballBackPosition = function(){ for(var i=0;i<This.actorNumber;i++){ var ball = This.ballActor[i]; dinámica.animate(ball, { x: ball.backX, y: ball.backY },{ tipo: dinámica[this.backDynamics], duración: 991, completo:this.changeStatus(ball) } }}// Obtener tipo|efecto de animación Circle.prototype.getAnimateType = function() { var selectType = document.getElementById(selectType); var selectDynamics = document.getElementById(selectDynamics); this.backType = selectType.options[selectType.options.selectedIndex].value;}//Restablecer círculo de extensión .prototype.ballbackType = función(){ si(este.backType == back){ this.ballBackPosition(); }else{ this.ballAutoPosition(); } this.ballActor = [];}// Dispersión aleatoria Circle.prototype.ballAutoPosition = function(ball){ for(var i= 0 ;i<this.actorNumber;i++){ this.changeStatus(this.ballActor[i]) }}// Cambiar el estado de la bola Circle.prototype.changeStatus = function(ball){ ball.status = 0; if(this.isPlay == true){ this.isPlay = false }}// Genera aleatoriamente los parámetros relevantes de cada círculo Circle; .prototype.generalRandomParam = function(){ for(var i=0;i<this.ballNumber;i++){ var ball = {}; ball.size = 1; Generar aleatoriamente el radio del círculo // Generar aleatoriamente el centro del círculo x coordenada ball.x = ramdomNumber(0+ball.size, this.iCanvasW-ball.size ball.y = ramdomNumber(0+ball.size, this.iCanvasH-ball); tamaño); bola.velocidadX = ramdomNumber(-1, 1); ball.speedY = ramdomNumber(-1, 1); ball.status = 0; ball.targetX = 0; ball.targetY = 0; ball.backX = 0; ball.backY = 0; cambiar la posición del círculo 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; } }}// Dibuja un círculo Circle.prototype.renderBall = function(ball){ this.ctx . fillStyle = #fff; this.ctx.beginPath(); // Esto debe agregarse con this.ctx.arc(ball.x, ball.y, ball.size, 0, 2 * Math.PI); this.ctx.closePath(); // Esto debe agregarse con this.ctx.fill();}// Juicio de colisión de bolas 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 } si (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;// Iniciar animación Circle.prototype.ballAnimate = function(){ var This = this var animateFrame = ventana.requestAnimationFrame || ventana.mozRequestAnimationFrame || window.msRequestAnimationFrame; (función mover(){ animte = animateFrame(mover); 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]); })();}// Generar una función de número aleatorio ramdomNumber(min, max) { return Math.random() * (max - min) + min;}
Después de leer el código, supongo que fue solo un alarde y no te dio el deseo de hacer esto. Sé que debes convencerte con los ojos y la boca. DEMOSTRACIÓN en línea: ejemplo de partículas dinámicas.
Nadie es perfecto y el código tampoco. El código que parece funcionar sin problemas tiene más o menos fallas. Actualmente, este efecto solo es compatible con chino. En cuanto al inglés, tengo que trabajar más duro, pase lo que pase, el inglés definitivamente se unirá más tarde, es solo cuestión de tiempo. También hay un atributo en el código que se usa para marcar si el texto generado se puede ejecutar nuevamente: this.isPlay, que todavía es un pequeño defecto. El cambio de estado de this.isPlay no cambia exactamente en el momento en que regresan las partículas. pero cambia el estado de antemano. Pero este estado no afectará la implementación completa del efecto de este ejemplo.
En este ejemplo, se usa la biblioteca Dynamics.js, principalmente para usar algunas funciones de movimiento para hacer que las partículas se muevan de manera más impresionante, eso es todo.
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.