Explicación:


2. Diseñar el lienzo con CSS

Agreguemos un estilo simple para darle a nuestro lienzo un fondo negro y asegurarnos de que se eliminen todo el relleno y los márgenes.

* {    margin: 0;    padding: 0;    box-sizing: border-box;}canvas {    background-color: black;}

Explicación:


3. Clase de partículas: creando la magia

La clase Particle es donde se encuentra el núcleo de la animación. Cada partícula se mueve a través del lienzo, dejando un rastro de sus ubicaciones pasadas, creando el efecto de flujo.

class Particle {    constructor(effect) {        this.effect = effect;        this.x = Math.floor(Math.random() * this.effect.width);        this.y = Math.floor(Math.random() * this.effect.height);        this.speedModifier = Math.floor(Math.random() * 5   1);        this.history = [{ x: this.x, y: this.y }];        this.maxLength = Math.floor(Math.random() * 200   10);        this.timer = this.maxLength * 2;        this.colors = [\\'#4C026B\\', \\'#8E0E00\\', \\'#9D0208\\', \\'#BA1A1A\\', \\'#730D9E\\'];        this.color = this.colors[Math.floor(Math.random() * this.colors.length)];    }    draw(context) {        context.beginPath();        context.moveTo(this.history[0].x, this.history[0].y);        for (let i = 1; i < this.history.length; i  ) {            context.lineTo(this.history[i].x, this.history[i].y);        }        context.strokeStyle = this.color;        context.stroke();    }    update() {        this.timer--;        if (this.timer >= 1) {            let x = Math.floor(this.x / this.effect.cellSize);            let y = Math.floor(this.y / this.effect.cellSize);            let index = y * this.effect.cols   x;            let angle = this.effect.flowField[index];            this.speedX = Math.cos(angle);            this.speedY = Math.sin(angle);            this.x  = this.speedX * this.speedModifier;            this.y  = this.speedY * this.speedModifier;            this.history.push({ x: this.x, y: this.y });            if (this.history.length > this.maxLength) {                this.history.shift();            }        } else if (this.history.length > 1) {            this.history.shift();        } else {            this.reset();        }    }    reset() {        this.x = Math.floor(Math.random() * this.effect.width);        this.y = Math.floor(Math.random() * this.effect.height);        this.history = [{ x: this.x, y: this.y }];        this.timer = this.maxLength * 2;    }}

Explicación:


4. Clase de efectos: organización de la animación

La clase Efecto maneja la creación de partículas y el campo de flujo en sí, que controla el movimiento de las partículas.

class Effect {    constructor(canvas) {        this.canvas = canvas;        this.width = this.canvas.width;        this.height = this.canvas.height;        this.particles = [];        this.numberOfParticles = 3000;        this.cellSize = 20;        this.flowField = [];        this.curve = 5;        this.zoom = 0.12;        this.debug = true;        this.init();    }    init() {        this.rows = Math.floor(this.height / this.cellSize);        this.cols = Math.floor(this.width / this.cellSize);        for (let y = 0; y < this.rows; y  ) {            for (let x = 0; x < this.cols; x  ) {                let angle = (Math.cos(x * this.zoom)   Math.sin(y * this.zoom)) * this.curve;                this.flowField.push(angle);            }        }        for (let i = 0; i < this.numberOfParticles; i  ) {            this.particles.push(new Particle(this));        }    }    drawGrid(context) {        context.save();        context.strokeStyle = \\'white\\';        context.lineWidth = 0.3;        for (let c = 0; c < this.cols; c  ) {            context.beginPath();            context.moveTo(c * this.cellSize, 0);            context.lineTo(c * this.cellSize, this.height);            context.stroke();        }        for (let r = 0; r < this.rows; r  ) {            context.beginPath();            context.moveTo(0, r * this.cellSize);            context.lineTo(this.width, r * this.cellSize);            context.stroke();        }        context.restore();    }    render(context) {        if (this.debug) this.drawGrid(context);        this.particles.forEach(particle => {            particle.draw(context);            particle.update();        });    }}

Explicación:


5. Dándole vida con el bucle de animación

Para que todo funcione, necesitamos un bucle de animación que borre continuamente el lienzo y vuelva a renderizar las partículas:

const effect = new Effect(canvas);function animate() {    ctx.clearRect(0, 0, canvas.width, canvas.height);    effect.render(ctx);    requestAnimationFrame(animate);}animate();

Explicación:


Conclusión

Al dividir las clases de Partículas y Efectos, hemos creado una animación de campo de flujo fluido y dinámico usando solo JavaScript estándar. La simplicidad del lienzo HTML, combinada con las funciones trigonométricas de JavaScript, nos permite crear estos fascinantes efectos visuales.

¡Siéntete libre de jugar con el recuento de partículas, los colores o la fórmula del campo de flujo para crear tus propios efectos únicos!

","image":"http://www.luping.net/uploads/20241022/17296041676717aa472ee02.jpg","datePublished":"2024-11-09T01:12:23+08:00","dateModified":"2024-11-09T01:12:23+08:00","author":{"@type":"Person","name":"luping.net","url":"https://www.luping.net/articlelist/0_1.html"}}
"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Pantalla de campo de flujo

Pantalla de campo de flujo

Publicado el 2024-11-09
Navegar:157

Flow Field Screen

Campos de flujo dinámico con Vanilla JS y HTML Canvas

¿Alguna vez te han hipnotizado las animaciones de partículas abstractas? Estas imágenes fluidas y dinámicas se pueden lograr con técnicas sorprendentemente simples utilizando JavaScript simple y el elemento lienzo HTML. En este artículo, analizaremos el proceso de creación de un campo de flujo que anima miles de partículas, dándoles un movimiento natural.

1. Configuración del proyecto

Para comenzar, necesitamos tres archivos: un archivo HTML para configurar el lienzo, un archivo CSS para diseñar y un archivo JavaScript para manejar la lógica.



    
    
    Flow Fields
    


    
    


Explicación:

  • Definimos un elemento donde se realizarán todas nuestras animaciones.
  • El archivo style.css se vinculará para aplicar estilo al lienzo.
  • La lógica de animación principal está contenida en script.js.

2. Diseñar el lienzo con CSS

Agreguemos un estilo simple para darle a nuestro lienzo un fondo negro y asegurarnos de que se eliminen todo el relleno y los márgenes.

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

canvas {
    background-color: black;
}

Explicación:

  • Establecer el margen y el relleno en cero garantiza que el lienzo ocupe toda la pantalla.
  • El fondo negro proporciona un bonito contraste para las partículas blancas.

3. Clase de partículas: creando la magia

La clase Particle es donde se encuentra el núcleo de la animación. Cada partícula se mueve a través del lienzo, dejando un rastro de sus ubicaciones pasadas, creando el efecto de flujo.

class Particle {
    constructor(effect) {
        this.effect = effect;
        this.x = Math.floor(Math.random() * this.effect.width);
        this.y = Math.floor(Math.random() * this.effect.height);
        this.speedModifier = Math.floor(Math.random() * 5   1);
        this.history = [{ x: this.x, y: this.y }];
        this.maxLength = Math.floor(Math.random() * 200   10);
        this.timer = this.maxLength * 2;
        this.colors = ['#4C026B', '#8E0E00', '#9D0208', '#BA1A1A', '#730D9E'];
        this.color = this.colors[Math.floor(Math.random() * this.colors.length)];
    }

    draw(context) {
        context.beginPath();
        context.moveTo(this.history[0].x, this.history[0].y);
        for (let i = 1; i = 1) {
            let x = Math.floor(this.x / this.effect.cellSize);
            let y = Math.floor(this.y / this.effect.cellSize);
            let index = y * this.effect.cols   x;
            let angle = this.effect.flowField[index];

            this.speedX = Math.cos(angle);
            this.speedY = Math.sin(angle);
            this.x  = this.speedX * this.speedModifier;
            this.y  = this.speedY * this.speedModifier;

            this.history.push({ x: this.x, y: this.y });
            if (this.history.length > this.maxLength) {
                this.history.shift();
            }
        } else if (this.history.length > 1) {
            this.history.shift();
        } else {
            this.reset();
        }
    }

    reset() {
        this.x = Math.floor(Math.random() * this.effect.width);
        this.y = Math.floor(Math.random() * this.effect.height);
        this.history = [{ x: this.x, y: this.y }];
        this.timer = this.maxLength * 2;
    }
}

Explicación:

  • Constructor: Cada partícula se inicializa con una posición y velocidad de movimiento aleatorias. La matriz de historial rastrea posiciones pasadas para crear senderos.
  • draw(): Esta función dibuja la ruta de la partícula en función de su historial. La partícula deja un rastro colorido que aumenta el efecto visual.
  • update(): Aquí, la posición de la partícula se actualiza calculando el ángulo desde el campo de flujo. La velocidad y la dirección están controladas por funciones trigonométricas.
  • reset(): Cuando la partícula termina su rastro, se restablece a una nueva ubicación aleatoria.

4. Clase de efectos: organización de la animación

La clase Efecto maneja la creación de partículas y el campo de flujo en sí, que controla el movimiento de las partículas.

class Effect {
    constructor(canvas) {
        this.canvas = canvas;
        this.width = this.canvas.width;
        this.height = this.canvas.height;
        this.particles = [];
        this.numberOfParticles = 3000;
        this.cellSize = 20;
        this.flowField = [];
        this.curve = 5;
        this.zoom = 0.12;
        this.debug = true;
        this.init();
    }

    init() {
        this.rows = Math.floor(this.height / this.cellSize);
        this.cols = Math.floor(this.width / this.cellSize);
        for (let y = 0; y  {
            particle.draw(context);
            particle.update();
        });
    }
}

Explicación:

  • Constructor: Inicializa las dimensiones del lienzo, el número de partículas y el campo de flujo.
  • init(): Calcula los ángulos para el campo de flujo combinando funciones trigonométricas para cada celda de la cuadrícula. Este campo influye en cómo se mueven las partículas.
  • drawGrid(): Dibuja la cuadrícula que divide el lienzo en celdas, utilizada durante la depuración.
  • render(): llama a los métodos de dibujo y actualización de cada partícula para animar las partículas en el lienzo.

5. Dándole vida con el bucle de animación

Para que todo funcione, necesitamos un bucle de animación que borre continuamente el lienzo y vuelva a renderizar las partículas:

const effect = new Effect(canvas);

function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    effect.render(ctx);
    requestAnimationFrame(animate);
}
animate();

Explicación:

  • clearRect(): borra el lienzo en cada cuadro para evitar dibujar sobre cuadros anteriores.
  • requestAnimationFrame: mantiene la animación fluida llamando recursivamente a la función animate().

Conclusión

Al dividir las clases de Partículas y Efectos, hemos creado una animación de campo de flujo fluido y dinámico usando solo JavaScript estándar. La simplicidad del lienzo HTML, combinada con las funciones trigonométricas de JavaScript, nos permite crear estos fascinantes efectos visuales.

¡Siéntete libre de jugar con el recuento de partículas, los colores o la fórmula del campo de flujo para crear tus propios efectos únicos!

Declaración de liberación Este artículo se reproduce en: https://dev.to/ibra-kdbra/flow-field-screen-567c?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3