Начало работы с HTML canvas

12.11.2017

HTML <canvas> элемент – это мощное решение для создания пиксельной графики в Web c использованием JavaScript. Canvas позволит вам создавать замечательные визуальные эффекты – нужно только немного попрактиковаться.

В этом туториале мы создадим canvas объект, добавим к нему простые визуальные эффекты и анимируем их.

01. Создаём страницу

По своей сути Canvas – это HTML элемент, который располагается на странице и растягивается таким образом, чтобы полностью покрывать необходимую область, на которой вы будете рисовать объекты.

Начнем с создания простой страницы и canvas объекта.

<!DOCTYPE html>
<html>
  <head>
  <meta charset='utf-8'/>
  <title>HTML Canvas Demo</title>
  <link rel='stylesheet' href='custom.css'/>
  <script src="canvas.js"></script>
  </head>
  <body>
  <canvas id="html-canvas">
  </body>
</html>

 02. Растягиваем canvas

Нам понадобится много пространства для работы, поэтому мы растянем наш canvas на весь экран. Мы также зададим для него черный фон, чтобы нам было проще работать и избавимся от отступов.

Этот CSS код должен помочь:

canvas {
  height: 100vh;
  width: 100vw;
  position: absolute;
  background-color: #000000;
  margin: 0;
  padding: 0;
}

03. Активируем canvas

Следующее, что нам понадобится сделать – это добавить немного JavaScript кода, чтобы подготовить наш canvas к работе. Создадим DOMContentLoaded ивент, чтобы скрипт не пытался запуститься до того, как canvas элемент будет готов.

Мы также сделаем так, чтобы разрешение canvas элемента соответствовало области, которую он покрывает: иначе canvas будет менять свой размер без изменения разрешения, что приведет к размытости и видимым пикселям.

document.addEventListener("DOMContentLoaded", function() {
  var canvas = document.getElementById("html-canvas");
  var circles = [];
  var radius = 50;
  canvas.width = canvas.clientWidth;
  canvas.height = canvas.clientHeight;
  var context = canvas.getContext("2d");
}, false);

04. Рисуем форму

Вы, наверное, заметили, что в предыдущем шаге мы создали нечто под названием “context”. С его помощью происходит рисование в canvas. Проще всего представить context как рисовальную кисть, с помощью которой мы можем рисовать линии, дуги и базовые фигуры. 

Сейчас мы можем пустить наш context в дело путем написания функции drawCircle, которая создаст дугу в 360 градусов – окружность, иными словами. Определим для context дугу (arc), зададим стили для границ и заливку, затем воспользуемся функциями fill() и stroke(), чтобы отрисовать формы (stroke рисует границы).

function drawCircle(x, y, radius, border, border_colour, fill_colour)
  {
  context.beginPath();
  context.arc(x,y,radius,0,2*Math.PI);
  context.strokeStyle = border_colour;
  context.fillStyle = fill_colour;
  context.lineWidth = border;
  context.closePath();
  context.fill();
  context.stroke();
  }

05. Создадим много окружностей

Отлично. Теперь у нас есть функция, которая рисует круги. Теперь немного дополним код из третьего шага, чтобы создать array, описывающий окружности. Он будет хранить координаты X и Y каждой окружности, цвет и расположение.

Мы создаем array вместо того, чтобы просто рисовать окружности, потому что это позволит нам анимировать круги путем повторения содержимого массива.

for (var i = 0; i < 20; i++) {
  var x = radius + (Math.random() * (canvas.width - (2 * radius)));
  var y = radius + (Math.random() * (canvas.height - (2 * radius)));
  var colour = randomColour();
  var direction = Math.random() * 2.0 * Math.PI;
  circles.push({x:x,y:y,colour:colour,direction:direction});
  draw();   }

06. Добавляем случайные цвета

В предыдущем шаге мы использовали пару новых функций. Начнем с randomColour(). Это фукнция, которая возвращает рандомный цвет в формате HEX. Использовать ее достаточно просто.

function randomColour() {
  var chars = '0123456789ABCDEF';
  var colour = '#';
  for (var i = 0; i < 6; i++) {
  colour += chars[Math.floor(Math.random() * 16)];
  }
  return colour; }

07. Рисуем графику на странице

Теперь мы наконец готовы использовать функцию draw(). Эта функция очищает canvas с помощью функции clearRect() – она поможет избежать отрисовывания одних объектов поверх других, когда мы начнем анимировать наши круги. Затем она пройдет через array, который мы создали ранее, и отрисует каждый круг отдельно с помощью нашей drawCircle функции.

function draw() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  circles.forEach(function (circle) {
  drawCircle(circle.x, circle.y, radius, 5, circle.colour, circle.colour);
    });   }

08. Анимируем формы

Если вы сейчас опробуете этот код, то увидите статичные круги, отрисованные на странице, но мы хотим сделать их анимированными. Дла этого мы дополним нашу draw() функцию. Прежде всего, мы используем значение circle.direction, которое находится в массиве, чтобы высчитать изменения в координатах X и Y наших кругов.

Затем мы используем встроенную функцию под названием requestAnimationFrame, которая рекурсивно вызывает вызывает функцию draw(). Эта функция позволяет браузеру решить, когда вызывать функцию снова, что позволит избежать добавления таймеров для вычисления времени, когда будет нарисован следующий кадр.

function draw() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  circles.forEach(function (circle) {
  circle.x = circle.x + Math.cos(circle.direction);
  circle.y = circle.y + Math.sin(circle.direction);
  drawCircle(circle.x, circle.y, radius, 5, circle.colour, circle.colour);
  });
  requestAnimationFrame(draw);
  }

 09. Отпрыгивание от краев страницы

Но еще не хватает одной вещи. Теперь круги просто исчезают за пределами экрана. Давайте сделаем так, чтобы они отпрыгивали обратно!

Для этого нам понадобится новая функция bounce(circle) внутри цикла функции draw(). Функция bounce определит, когда круг находится на краю экрана и отрегулирует направление движения.

function bounce(circle) {
  if (((circle.x - radius) < 0) || ((circle.y - radius) < 0) || ((circle.x + radius) > canvas.width) || ((circle.y + radius) > canvas.height))  {
  circle.direction += (Math.PI / 2);
  }
  if (circle.direction > (2 * Math.PI)) {
  circle.direction -= (2 * Math.PI);
  }
}

Canvas анимация готова!


Читайте также: 


Перевод статьи Get started with HTML canvas

Автор оригинального текста: Simon Jones