Анимация частиц на Canvas: фиолетовые круги в движении

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

<!-- Yandex.RTB R-A-6626549-1 -->
<div id="yandex_rtb_R-A-6626549-1"></div>
<script>
window.yaContextCb.push(() => {
    Ya.Context.AdvManager.render({
        "blockId": "R-A-6626549-1",
	"renderTo": "yandex_rtb_R-A-6626549-1"
    })
})
</script>

Начало работы

Начнем с HTML-разметки, которая включает в себя элемент <canvas> для рендеринга анимации.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Анимация частиц: Фиолетовые круги</title>
  <style>
    body {
      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAI0lEQVQIW2NkwAT/GdHE/gP5jMiCYAGQIpggXAAmiCIAEgQAAE4FBbECyZcAAAAASUVORK5CYII=) #222;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }
  </style>
</head>
<body>
  <canvas id="canvas"></canvas>
</body>
</html>

Здесь мы устанавливаем фон страницы с помощью CSS-свойства background, используя темный оттенок. Мы также обеспечиваем, чтобы тело страницы не имело полей и отступов, и устанавливаем overflow: hidden, чтобы скрыть любые элементы, выходящие за пределы видимой области.

JavaScript: Класс Particles

Теперь перейдем к JavaScript-части, где мы определим класс Particles, который будет управлять созданием и анимацией частиц.

/**
 * Generates random particles using canvas
 * 
 * @class Particles
 * @constructor
 */
function Particles() {
  // particle colors
  this.colors = [
    '128, 0, 255', // Purple
    '255, 0, 255', // Magenta
    '255, 255, 255' // White
  ];
  // adds gradient to particles on true
  this.blurry = true;
  // adds white border
  this.border = false;
  // particle radius min/max
  this.minRadius = 5;
  this.maxRadius = 50;
  // particle opacity min/max
  this.minOpacity = 0.005;
  this.maxOpacity = 0.5;
  // particle speed min/max
  this.minSpeed = 0.05;
  this.maxSpeed = 0.5;
  // frames per second
  this.fps = 60;
  // number of particles
  this.numParticles = 150;
  // required canvas variables
  this.canvas = document.getElementById('canvas');
  this.ctx = this.canvas.getContext('2d');
}

В конструкторе класса Particles мы определяем различные параметры, которые будут управлять поведением частиц. Сюда входят цвета, радиус, прозрачность, скорость и количество частиц.

Инициализация и рендеринг

Далее мы определим методы для инициализации и рендеринга canvas.

/**
 * Initializes everything
 * @method init
 */
Particles.prototype.init = function() {
  this.render();
  this.createCircle();
}

/**
 * Sets canvas size and updates values on resize
 * @method render
 */
Particles.prototype.render = function() {
  var self = this;
  var wHeight = window.innerHeight;
  var wWidth = window.innerWidth;

  self.canvas.width = wWidth;
  self.canvas.height = wHeight;

  window.addEventListener('resize', function() {
    self.render();
  });
}

Метод init вызывает render для настройки canvas и createCircle для создания частиц. Метод render устанавливает размер canvas в соответствии с размерами окна и обновляет его при изменении размера окна.

Создание и рисование частиц

Теперь мы создадим частицы и нарисуем их на canvas.

/**
 * Randomly creates particle attributes
 * @method createCircle
 */
Particles.prototype.createCircle = function() {
  var particle = [];

  for (var i = 0; i < this.numParticles; i++) {
    var self = this;
    var color = self.colors[~~(self._rand(0, self.colors.length))];

    particle[i] = {
      radius: self._rand(self.minRadius, self.maxRadius),
      xPos: self._rand(0, self.canvas.width),
      yPos: self._rand(0, self.canvas.height),
      xVelocity: self._rand(self.minSpeed, self.maxSpeed),
      yVelocity: self._rand(self.minSpeed, self.maxSpeed),
      color: 'rgba(' + color + ',' + self._rand(self.minOpacity, self.maxOpacity) + ')'
    };

    self.draw(particle, i);
  }
  self.animate(particle);
}

/**
 * Draws particles on canvas
 * @param {array} Particle array from createCircle method
 * @param {number} i value from createCircle method
 * @method draw
 */
Particles.prototype.draw = function(particle, i) {
  var self = this;
  var ctx = self.ctx;

  if (self.blurry === true) {
    var grd = ctx.createRadialGradient(particle[i].xPos, particle[i].yPos, particle[i].radius, particle[i].xPos, particle[i].yPos, particle[i].radius / 1.25);
    grd.addColorStop(1.000, particle[i].color);
    grd.addColorStop(0.000, 'rgba(34, 34, 34, 0)');
    ctx.fillStyle = grd;
  } else {
    ctx.fillStyle = particle[i].color;
  }

  if (self.border === true) {
    ctx.strokeStyle = '#fff';
    ctx.stroke();
  }

  ctx.beginPath();
  ctx.arc(particle[i].xPos, particle[i].yPos, particle[i].radius, 0, 2 * Math.PI, false);
  ctx.fill();
}

Метод createCircle создает массив частиц с случайными атрибутами, такими как радиус, позиция и скорость. Затем мы вызываем метод draw для рисования каждой частицы на canvas. Метод draw использует контекст canvas для рисования кругов с градиентом или сплошным цветом, в зависимости от значения blurry.

Анимация частиц

Чтобы создать анимацию, мы будем обновлять позиции частиц и перерисовывать их на каждой кадре.

/**
 * Animates particles
 * @param {array} particle value from createCircle & draw methods
 * @method animate
 */
Particles.prototype.animate = function(particle) {
  var self = this;
  var ctx = self.ctx;

  setInterval(function() {
    self.clearCanvas();
    for (var i = 0; i < self.numParticles; i++) {
      particle[i].xPos += particle[i].xVelocity;
      particle[i].yPos -= particle[i].yVelocity;

      if (particle[i].xPos > self.canvas.width + particle[i].radius || particle[i].yPos > self.canvas.height + particle[i].radius) {
        self.resetParticle(particle, i);
      } else {
        self.draw(particle, i);
      }
    }
  }, 1000 / self.fps);
}

Метод animate использует setInterval для обновления позиций частиц на каждой кадре. Мы проверяем, не вышли ли частицы за пределы canvas, и если да, то вызываем метод resetParticle для их перемещения обратно на экран.

Обновление частиц и очистка canvas

Мы добавим методы для обновления частиц и очистки canvas.

/**
 * Resets position of particle when it goes off screen
 * @param {array} particle value from createCircle & draw methods
 * @param {number} i value from createCircle method
 * @method resetParticle
 */
Particles.prototype.resetParticle = function(particle, i) {
  var self = this;
  var random = self._rand(0, 1);

  if (random > 0.5) {
    particle[i].xPos = -particle[i].radius;
    particle[i].yPos = self._rand(0, self.canvas.height);
  } else {
    particle[i].xPos = self._rand(0, self.canvas.width);
    particle[i].yPos = self.canvas.height + particle[i].radius;
  }
  self.draw(particle, i);
}

/**
 * Clears canvas between animation frames
 * @method clearCanvas
 */
Particles.prototype.clearCanvas = function() {
  this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}

Метод resetParticle случайным образом помещает частицу обратно на экран, если она выходит за его пределы. Метод clearCanvas очищает canvas перед рисованием новых кадров.

Запуск анимации

Наконец, мы создадим экземпляр класса Particles и запустим анимацию.

// go go go!
var particle = new Particles().init();

Заключение

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