Advertisement
  1. Web Design
  2. HTML/CSS
  3. SVG

Руководство для начинающих по рисованию 2D-графики с помощью Two.js

Scroll to top
Read Time: 10 min

() translation by (you can also view the original English article)

Two.js - API, который упрощает создание 2D фигур используя код. Следуйте дальше, и вы узнаете, как создавать и анимировать фигуры с помощью JavaScript.

Two.js является универсальным рендерером, поэтому вы можете полагаться на тот же API для рисования с помощью Canvas, SVG или WebGL. В библиотеке есть много методов, которые можно использовать для управления тем, как на экране появляются разные фигуры или как они анимируются.

Установка

Несжатая версия библиотеки имеет размер около 128 КБ, а сжатая версия - 50 КБ. Если вы используете последнюю версию, вы можете уменьшить размер библиотеки с помощью специальной сборки.

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

Создание базовой формы

Во-первых, вам нужно сообщить Two.js об элементе, на котором вы хотите рисовать и анимировать свои фигуры. Вы можете передать некоторые параметры в конструктор Two, чтобы установить настройки.

Задайте тип рендерера, используя свойство type. Вы можете указать значение, подобное svg, webgl, canvas и т.д. По умолчанию type установлен в svg. Ширина и высота пространства для рисования могут быть заданы с использованием параметров width и height. Вы также можете установить пространство чертежа на полный доступный экран, используя параметр fullscreen. Если для параметра fullscreen установлено значение true, значения width и hight будут игнорироваться.

Наконец, вы можете задать, чтобы Two.js автоматически запускал анимацию, с помощью булевого параметра  autostart.

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

Вы можете нарисовать линию, используя two.makeLine(x1, y1, x2, y2). Здесь (x1, y1) - координаты первой конечной точки, а (x2, y2) - координаты второй конечной точки. Эта функция вернет объект Two.Line, который может быть сохранен в переменной для дальнейшей обработки в более поздней точке.

Аналогичным образом вы можете нарисовать нормальные и закругленные прямоугольники, используя two.makeRectangle(x, y, width, height) и two.makeRoundedRectangle(x, y, width, height, radius) соответственно. Помните, что x и y определяют центр прямоугольника, а не его верхние левые координаты, как многие другие библиотеки. Параметры width и height будут определять размер прямоугольника. Параметр radius используется для указания значения радиуса для закругленного угла.

Вы также можете отображать круги и эллипсы на веб-странице с использованием two.makeCircle(x, y, radius) и two.makeEllipse(x, y, width, height) соответственно. Подобно прямоугольникам, параметры x и y определяют центр круга или эллипса. Установка для width и height одного и того же значения в случае эллипса сделает его кругом.

Одним из полезных методов в Two.js, который вы часто будете использовать, является two.makeGroup(objects). Вы можете либо передать список разных объектов, либо передать массив объектов, путей или групп в качестве параметра этого метода. Он также вернет объект Two.Group.

Манипулирование объектами в группе

После того, как вы создали группу, вы можете манипулировать сразу всеми детьми, используя свойства, которые группа предоставляет вам.

Свойства stroke и fill можно использовать для установки цвета штриха и заливки для всех детей в группе. Они будут принимать все допустимые формы, в которых вы можете представлять цвет в CSS. Это означает, что вы можете использовать RGB, HSL или шестнадцатеричную нотацию. Вы также можете просто использовать название цвета, например, orange, red или blue. Аналогичным образом вы можете установить значения для всех других свойств, таких как linewidth, opacity, miter и cap. Можно удалить заливку и обводку у всех детей в группе, используя методы noFill() и noStroke().

Можно также применить другие физические преобразования, такие как scale, rotation и translation. Эти преобразования будут применяться к отдельным объектам. Добавление новых объектов в группу и их удаление легко делается с помощью методов add() и remove().

Определение градиентов и написание текста

Вы можете определить как линейные, так и радиальные градиенты в Two.js. Определение градиента не означает, что он будет отображаться автоматически на экране, но он будет доступен вам при настройке значений fill или stroke различных объектов.

Вы можете определить линейный градиент, используя two.makeLinearGradient(x1, y1, x2, y2, stop). Значения x1 и y1 определяют координаты начала градиента. Аналогично, значения x2 и y2 определяют координаты конца градиента. Параметр stop - массив экземпляров Two.Stop. Они определяют цвета каждой части массива и где каждый цвет переходит в следующий. Они могут быть определены с использованием нового Two.Stop(offset, color, opacity), где offset определяет точку на градиенте, где этот конкретный цвет должен быть полностью отображен. Параметр color определяет цвет градиента в конкретной точке. Вы можете использовать любые допустимые цветовые представления CSS в качестве значения. Наконец, параметр opacity определяет прозрачность цвета. Прозрачность необязательна, и она может иметь любое значение от 0 до 1.

Вы можете определить радиальные градиенты аналогичным образом, используя two.makeRadialGradient(x, y, radius, stops, fx, fy). В этом случае значения x и y определяют центр градиента. Параметр radius указывает, насколько должен расширяться градиент. Вы также можете передать массив остановок этому методу, чтобы установить цветовой состав градиентов. Параметры fx и fy являются необязательными, и их можно использовать для указания фокальной позиции для градиента.

Ознакомьтесь с некоторыми типами градиента и их кодом в CodePen ниже.

Помните, что положения градиентов x и y относятся к началу формы, которую они пытаются заполнить. Например, радиальный градиент, который должен заполнять фигуру из центра, всегда будет иметь x и y, равные нулю.

Two.js также позволяет вам писать текст в области рисования и обновлять его позже в соответствии с вашими потребностями. Для этого требуется использование метода two.makeText(message, x, y, styles). Из имени параметров видно, что message является фактическим текстом, который вы хотите записать. Параметры x и y являются координатами точки, которая будет выступать в качестве центра для написания текста. Параметр styles - это объект, который может использоваться для установки значений большого набора свойств.

Вы можете использовать стили для установки значений свойств, таких как font-family, size и alignment. Вы также можете указать значение свойств, таких как fill, stroke, opacity, rotation, scale и translation.

Создание проекта Two.js

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

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

1
var centerX = window.innerWidth / 2;
2
var centerY = window.innerHeight / 2;
3
4
var elem = document.getElementById("atoms");
5
6
var elementNames = [
7
  "",
8
  "Hydrogen",
9
  "Helium",
10
  "Lithium",
11
  "Beryllium",
12
  "Boron",
13
  "Carbon",
14
  "Nitrogen",
15
  "Oxygen",
16
  "Fluorine",
17
  "Neon"
18
];
19
20
var styles = {
21
  alignment: "center",
22
  size: 36,
23
  family: "Lato"
24
};
25
26
var nucleusCount = 10;
27
var nucleusArray = Array();
28
29
var electronCount = 10;
30
var electronArray = Array();
31
32
function intRange(min, max) {
33
  return Math.random() * (max - min) + min;
34
}

В приведенном выше коде хранятся координаты центра нашего окна в переменных centerX и centerY. Они будут использованы позже, чтобы поместить наш атом в центр. Массив elementNames содержит имена первых десяти элементов периодической таблицы. Индекс каждого имени соответствует числу электронов и протонов этого элемента и начинается с пустой строки. Объект styles содержит свойства для стилизации текстового объекта.

Мы также определили функцию intRange() для получения случайного целочисленного значения в заданных экстремумах.

1
var two = new Two({ fullscreen: true }).appendTo(elem);
2
3
var protonColor = two.makeRadialGradient(
4
  0,
5
  0,
6
  15,
7
  new Two.Stop(0, "red", 1),
8
  new Two.Stop(1, "black", 1)
9
);
10
11
var neutronColor = two.makeRadialGradient(
12
  0,
13
  0,
14
  15,
15
  new Two.Stop(0, "blue", 1),
16
  new Two.Stop(1, "black", 1)
17
);
18
19
for (i = 0; i < nucleusCount; i++) {
20
  nucleusArray.push(two.makeCircle(intRange(-10, 10), intRange(-10, 10), 8));
21
}
22
23
nucleusArray.forEach(function(nucleus, index) {
24
  if (index % 2 == 0) {
25
    nucleus.fill = protonColor;
26
  }
27
  if (index % 2 == 1) {
28
    nucleus.fill = neutronColor;
29
  }
30
  nucleus.noStroke();
31
});

Это создает экземпляр Two и определяет два радиальных градиента. Красные/черные радиальные градиенты будут представлять протоны, а синие/черные градиенты будут представлять собой нейтроны.

Мы использовали функцию intRange() для размещения всех этих нейтронов и протонов в пределах 20 пикселей друг от друга. Метод makeCircle() устанавливает радиус этих протонов и нейтронов в 10 пикселей. После этого мы перебираем nucleusArray и поочередно заполняем каждый круг другим градиентом.

1
for (var i = 0; i < 10; i++) {
2
  if (i < 2) {
3
    var shellRadius = 50;
4
    var angle = i * Math.PI;
5
    electronArray.push(
6
      two.makeCircle(
7
        Math.cos(angle) * shellRadius,
8
        Math.sin(angle) * shellRadius,
9
        5
10
      )
11
    );
12
  }
13
  if (i >= 2 && i < 10) {
14
    var shellRadius = 80;
15
    var angle = (i - 2) * Math.PI / 4;
16
    electronArray.push(
17
      two.makeCircle(
18
        Math.cos(angle) * shellRadius,
19
        Math.sin(angle) * shellRadius,
20
        5
21
      )
22
    );
23
  }
24
}

Размещение нейтронов и протонов внутри ядра было легким. Однако, правильное размещение электронов на равномерном расстоянии потребует немного математики. Мы используем переменную shellRadius, чтобы указать расстояние от разных электронных оболочек от ядра. Целый круг покрывает угол, равный 2 Пи радиан. Мы можем размещать разные электроны равномерно, распределяя между ними 2 Пи радианы.

Функции Math.cos() и Math.sin() используются для разделения вертикальной и горизонтальной составляющих вектора положения разных электронов на основе их угла.

1
var orbitA = two.makeCircle(centerX, centerY, 50);
2
orbitA.fill = "transparent";
3
orbitA.linewidth = 2;
4
orbitA.stroke = "rgba(0, 0, 0, 0.1)";
5
6
var orbitB = two.makeCircle(centerX, centerY, 80);
7
orbitB.fill = "transparent";
8
orbitB.linewidth = 2;
9
orbitB.stroke = "rgba(0, 0, 0, 0.1)";
10
11
var groupElectronA = two.makeGroup(electronArray.slice(0, 2));
12
groupElectronA.translation.set(centerX, centerY);
13
groupElectronA.fill = "orange";
14
groupElectronA.linewidth = 1;
15
16
var groupElectronB = two.makeGroup(electronArray.slice(2, 10));
17
groupElectronB.translation.set(centerX, centerY);
18
groupElectronB.fill = "yellow";
19
groupElectronB.linewidth = 1;
20
21
var groupNucleus = two.makeGroup(nucleusArray);
22
groupNucleus.translation.set(centerX, centerY);

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

1
two
2
  .bind("update", function(frameCount) {
3
    groupElectronA.rotation += 0.025 * Math.PI;
4
    groupElectronB.rotation += 0.005 * Math.PI;
5
    groupNucleus.rotation -= 0.05;
6
  })
7
  .play();
8
9
var text = two.makeText("", centerX, 100, styles);
10
11
nucleusArray.forEach(function(nucleus, index) {
12
  nucleus.opacity = 0;
13
});
14
15
electronArray.forEach(function(electron, index) {
16
  electron.opacity = 0;
17
});

Эта часть кода устанавливает непрозрачность отдельных электронов и протонов до нуля. Он также сообщает Two.js, вращать электроны и протоны на определенных скоростях.

1
visible = 0;
2
3
document.addEventListener("click", function(event) {
4
  if (visible < nucleusArray.length) {
5
    nucleusArray[visible].opacity = 1;
6
    electronArray[visible].opacity = 1;
7
    visible++;
8
    text.value = elementNames[visible];
9
  }
10
  else {
11
    nucleusArray.forEach(el => el.opacity=0);
12
    electronArray.forEach(el => el.opacity=0);
13
    visible = 0;
14
    text.value = elementNames[0];
15
  }
16
});         
17

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

Попробуйте щелкнуть или нажать в следующем демо CodePen, чтобы увидеть первые десять элементов периодической таблицы.

Последние мысли

Мы начали это руководство с краткого введения в библиотеку Two.js и того, как его можно использовать для рисования фигур, таких как прямоугольники, круги и эллипсы. После этого мы обсудили, как мы можем группировать разные объекты вместе, чтобы манипулировать ими всеми сразу. Мы использовали эту способность для группировки элементов для перевода и вращения их в синхронизации. Эти инструменты объединились в нашей анимации атомов первых десяти элементов в периодической таблице.

Как вы можете видеть, создание анимированной 2D-графики очень просто при использовании Two.js. Основной задачей этого руководства было помочь вам быстро начать работу, поэтому мы осветили только основы. Однако, вы можете прочитать официальную документацию, чтобы узнать больше о библиотеке!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.