Русский
Русский
English
Статистика
Реклама

Конфетти на канвасе

Привет Хабр! Попалась недавно интересная вещичка , которая создает эффект конфетти на страничке. Решил глянуть , что же там внутри находится, как работает и познакомиться с канвасом поближе. Подробности под катом.

Вступление

Повествование будет вестись с точки зрения человека, который первый раз в жизни увидел канвас ( ладно, второй, первой была вот эта статья с хабра про фрактальные снежинки) и хочет почерпнуть себе разные полезные моменты, которые , возможно, захочется использовать в будущем. Отталкивался от исходного кода библиотечки canvas-confetti.

Настройки

Удобно представить себе некую пушку, которая находится в некой точке origin, наклонена под углом angle и стреляет зарядом в виде конуса, который отклоняется от направления выстрела влево и вправо на угол spread со скоростью startVelocity . Потом частицы начинают терять скорость в зависимости от сопротивления воздуха decay и падать под действием силы тяжести gravity. Еще есть параметры для колличества частиц, цвета, формы, размера ( particleCount, colors, shapes, scalar). Достаточно добавить только интересующие опции, остальные подтянутся по умолчанию.

confetti({  particleCount: 100,  startVelocity: 30,  spread: 360,  origin: {    x: Math.random(),    y: Math.random() - 0.2  }}

Полезные моменты внутри

Штука, которая обеспечивает 60 кадров в секунду с помощью requestAnimationFrame , если есть или откатывается к setTimeout

var raf = (function () {  var TIME = Math.floor(1000 / 60);  var frame, cancel;  var frames = {};  var lastFrameTime = 0;  if (typeof requestAnimationFrame === 'function' && typeof cancelAnimationFrame === 'function') {    frame = function (cb) {      var id = Math.random();      frames[id] = requestAnimationFrame(function onFrame(time) {        if (lastFrameTime === time || lastFrameTime + TIME - 1 < time) {          lastFrameTime = time;          delete frames[id];          cb();        } else {          frames[id] = requestAnimationFrame(onFrame);        }      });      return id;    };    cancel = function (id) {      if (frames[id]) {        cancelAnimationFrame(frames[id]);      }    };  } else {    frame = function (cb) {      return setTimeout(cb, TIME);    };    cancel = function (timer) {      return clearTimeout(timer);    };  }  return { frame: frame, cancel: cancel };}());

Заполнение канвасом всей видимой области странички с помощью createElement, appendChild, clientWidth, clientHeight

function getCanvas(zIndex) {    var canvas = document.createElement('canvas');    canvas.style.position = 'fixed';    canvas.style.top = '0px';    canvas.style.left = '0px';    canvas.style.pointerEvents = 'none';    canvas.style.zIndex = zIndex;    return canvas;  }// ..... document.body.appendChild(canvas);// .....function setCanvasWindowSize(canvas) {  canvas.width = document.documentElement.clientWidth;  canvas.height = document.documentElement.clientHeight;}

Получение двумерного контекста канваса с getContext

var context = canvas.getContext('2d');

Чистка, которая происходит перед отрисовкой каждого кадра с помощью clearRect в методе update

context.clearRect(0, 0, size.width, size.height);

Для создания каждого кадра вызывается update, внутри которого для каждой "конфетиточки" вызывается код, который считает ее геометрические координаты и рисует ее с помощью методов контекста beginPath, moveTo, lineTo, closePath и fill. Также каждая фетишка отслеживает сколько у нее прошло кадров-апдейтов и потом, когда у всех фетишек закончатся кадры, анимация отрапортует о своем завершении.

function updateFetti(context, fetti) {// ...    // пара десятков строк косинусов и синусов, которые посчитают новые координаты для конфетишки    // ...    context.fillStyle = 'rgba(' + fetti.color.r + ', ' + fetti.color.g + ', ' + fetti.color.b + ', ' + (1 - progress) + ')';    context.beginPath();    // ...    context.moveTo(Math.floor(fetti.x), Math.floor(fetti.y));    context.lineTo(Math.floor(fetti.wobbleX), Math.floor(y1));    context.lineTo(Math.floor(x2), Math.floor(y2));    context.lineTo(Math.floor(x1), Math.floor(fetti.wobbleY));    context.closePath();    context.fill();    // ...// когда кадры закончатся фетишка отфильтруется из массива частиц для апдейта    return fetti.tick < fetti.totalTicks;  }

Заключение

Надеюсь этот пост поможет кому-нибудь быстро ознакомится с рисованием на двумерном канвасе. В исходнике есть много полезного касательно анимации из воркера и геометрии. Желающие могут ознакомиться более детально по ссылке вначале статьи.

Источник: habr.com
К списку статей
Опубликовано: 22.01.2021 14:05:41
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Javascript

Canvas

Учебный процесс в it

Html5

Confetti

Разработка

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru