Объяснение:


2. Стилизация холста с помощью CSS

Давайте добавим простой стиль, чтобы придать нашему холсту черный фон и убедиться, что все отступы и поля удалены.

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

Объяснение:


3. Класс частиц: творим волшебство

Класс Particle — это основа анимации. Каждая частица движется по холсту, оставляя след из своих прошлых местоположений, создавая эффект плавности.

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;    }}

Объяснение:


4. Класс эффектов: организация анимации

Класс Effect управляет созданием частиц и самим полем потока, которое управляет движением частиц.

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();        });    }}

Объяснение:


5. Оживление с помощью цикла анимации

Чтобы все работало, нам нужен цикл анимации, который постоянно очищает холст и повторно отображает частицы:

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

Объяснение:


Заключение

Разбив классы Particle и Effect, мы создали плавную и динамичную анимацию поля потока, используя только стандартный JavaScript. Простота HTML-холста в сочетании с тригонометрическими функциями JavaScript позволяет нам создавать эти завораживающие визуальные эффекты.

Не стесняйтесь экспериментировать с количеством частиц, цветами или формулой поля потока, чтобы создавать свои собственные уникальные эффекты!

","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"}}
«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Экран поля потока

Экран поля потока

Опубликовано 9 ноября 2024 г.
Просматривать:232

Flow Field Screen

Динамические поля потока с использованием Vanilla JS и HTML Canvas

Вы когда-нибудь были загипнотизированы анимацией абстрактных частиц? Эти плавные, динамичные визуальные эффекты могут быть достигнуты с помощью удивительно простых методов, используя простой JavaScript и элемент холста HTML. В этой статье мы разберем процесс создания поля потока, которое оживляет тысячи частиц, придавая им естественное движение.

1. Настройка проекта

Для начала нам нужны три файла: файл HTML для настройки холста, файл CSS для стилизации и файл JavaScript для обработки логики.



    Flow Fields

Объяснение:

  • Мы определяем элемент , в котором будет происходить вся наша анимация.
  • Стиль.css будет связан со стилем холста.
  • Основная логика анимации содержится в script.js.

2. Стилизация холста с помощью CSS

Давайте добавим простой стиль, чтобы придать нашему холсту черный фон и убедиться, что все отступы и поля удалены.

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

canvas {
    background-color: black;
}

Объяснение:

  • Установка нулевых полей и отступов гарантирует, что холст заполнит весь экран.
  • Черный фон обеспечивает приятный контраст с белыми частицами.

3. Класс частиц: творим волшебство

Класс Particle — это основа анимации. Каждая частица движется по холсту, оставляя след из своих прошлых местоположений, создавая эффект плавности.

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;
    }
}

Объяснение:

  • Конструктор: каждая частица инициализируется случайным положением и скоростью движения. Массив истории отслеживает прошлые позиции для создания следов.
  • draw(): эта функция рисует путь частицы на основе ее истории. Частица оставляет красочный след, который усиливает визуальный эффект.
  • update(): Здесь положение частицы обновляется путем расчета угла по полю потока. Скорость и направление контролируются тригонометрическими функциями.
  • reset(): Когда частица завершает свой след, она перемещается в новое случайное место.

4. Класс эффектов: организация анимации

Класс Effect управляет созданием частиц и самим полем потока, которое управляет движением частиц.

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();
        });
    }
}

Объяснение:

  • Конструктор: инициализирует размеры холста, количество частиц и поле потока.
  • init(): вычисляет углы поля потока путем объединения тригонометрических функций для каждой ячейки сетки. Это поле влияет на движение частиц.
  • drawGrid(): рисует сетку, разделяющую холст на ячейки, используемые при отладке.
  • render(): вызывает методы рисования и обновления для каждой частицы, чтобы анимировать частицы на холсте.

5. Оживление с помощью цикла анимации

Чтобы все работало, нам нужен цикл анимации, который постоянно очищает холст и повторно отображает частицы:

const effect = new Effect(canvas);

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

Объяснение:

  • clearRect(): очищает холст в каждом кадре, чтобы избежать рисования поверх предыдущих кадров.
  • requestAnimationFrame: обеспечивает плавность анимации за счет рекурсивного вызова функции animate().

Заключение

Разбив классы Particle и Effect, мы создали плавную и динамичную анимацию поля потока, используя только стандартный JavaScript. Простота HTML-холста в сочетании с тригонометрическими функциями JavaScript позволяет нам создавать эти завораживающие визуальные эффекты.

Не стесняйтесь экспериментировать с количеством частиц, цветами или формулой поля потока, чтобы создавать свои собственные уникальные эффекты!

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/ibra-kdbra/flow-field-screen-567c?1. Если есть какие-либо нарушения, свяжитесь с [email protected], чтобы удалить их.
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3