Рисование на JavaScript с помощью Paper.js, Processing.js, Raphael.js


При создании дизайна сайта, очень удобно использовать рисунки и анимацию основанную на JavaScript фреймверках. Это быстро, удобно и красиво. Но…

Перед тем как начать рисовать что-то в своем браузере, задайте себе три вопроса:

  1. Нужна ли вам поддержка старых браузеров? Если ответ ДА, вашим выбором будет Raphael.js. Он поддерживается браузерами начиная с 7 и 3. Некоторые элементы графики будут работать даже в 6. Хотя эта библиотека не поддерживает технологий которые предоставляют следующие библиотеки…
  1. Нужна ли вам поддержка Android устройств? Android не поддерживает SVG графики, поэтому вам придется использовать Paper.js или Processing.js. Ходят слухи, что Android 4 поддерживает обработку SVG, но большинство устройств работают под старой версией Android.
  1. Нужна ли вам интерактивность? Raphael и Paper.js предрасположены на интерактивность через клики, перетягивания и касания. Processing.js не поддерживает никаких объектных событий, поэтому действия пользователя будет сложно отслеживать. Processing.js может рисовать отличную анимацию на главной странице, но для интерактивных приложений лучше использовать другие средства.

Paper.js, Processing.js и Raphael лидирующие библиотеки для рисования на веб страницах средствами javascript. Вы можете использовать технологию Flash, но эти три отлично работают с HTML5 и поддерживают наибольшее число браузеров.

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

Код использованный в этой статье доступен на демо странице.

Обзор фреймверков для рисования

Фреймверки для рисования на javascript

Они все основаны на JavaScript, но рисование происходит немного разными способами. Raphael написан на чистом javascript коде, но Paper.js использует PaperScript, и Processing.js использует собственный скрипт.

Они все поддерживают FireFox, Opera, Chrome и Safari, но Internet Explorer исключение – Paper.js и Processing.js используют тег canvas, который поддерживается в IE9 и выше.

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

Processing.js основан на фреймверку Processing, который запускается на Java виртуальной машине. При написании код может нагадывать Java, но он более похож на JavaScript и не нуждается в сложном синтаксисе.

Рисование с помощью этих троих библиотек простое, если вы когда либо сталкивались с JavaScript.

Начнем

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

Настройка Paper.js

<head>
<script src="paper.js" type="text/javascript" charset="utf-8"></script>
<script type="text/paperscript" canvas="paperCircle" src="paper_circle.pjs" id="script"></script>
</head>
<body>
<canvas id="paperCircle" class="canvas" width="200" height="200" style="background-color: white;"></canvas>

Paper.js потребует тип скрипта text/paperscript и ID canvas тега, который вы будете использовать.

Настройка Processing.js

<head>
<script src="processing.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<canvas width="200" height="200" class="canvas" data-processing-sources="processing_circle.java"></canvas>

Processing.js использует data-processing-sources атрибут canvas тега, для загрузки вашего рисунка. Я использую расширение .java для исходного файла Processing библиотеки, в таком случае мой редактор правильно подсвечивает код. Некоторые автора используют .pde или .pjs расширение. Выбирать вам.

Настройка Raphael

<head>
<script src="raphael-min.js" type="text/javascript" charset="utf-8"></script>
<script src="raphael_circle.js" type="text/javascript" charset="utf-8"></script>
</head>

Raphael подключается как и любой другой файл . Он отлично работает с функциями jQuery или другими JavaScript фреймверками.

Теперь начнем рисовать.

Объектно-ориентированное рисование на JavaScript

Как Paper.js так и Raphael используют объектно-ориентированное рисование: вы можете нарисовать круг и получить объект круга. Processing.js рисует круг и ничего не возвращает обратно. Следующий пример все разъяснит. Давайте начнем с круга в центре экрана в точке 100, 100.

Рисунок на javascript

Paper.js:

var circle = new Path.Circle(new Point(100, 100), 10);
circle.fillColor = '#ee2a33';

Raphaël:

var paper = Raphael('raphaelCircle', 200, 200);
var c = paper.ellipse(100, 100, 10, 10);
c.attr({'fill': '#00aeef', 'stroke': '#00aeef'});

Processing.js:

void setup() {
   size(200, 200);
}

void draw() {
   background(#ffffff);
   translate(100, 100);
   fill(#52b755);
   noStroke();
   ellipse(0, 0, 20, 20);
}

Каждый сниппет кода рисует тот же круг. Разница в том, что вы можете с этим делать.

Paper.js создает круг как path объект. Мы можем использовать этот объект и изменить его позже. В Paper.js, circle.fillColor = 'red'; - делает наш круг красным, и circle.scale(2) – увеличивает круг в два раза.

Raphaël также объектно-ориентированная модель. Мы также можем изменить цвет круга с помощью circle.attr('fill', 'red');, также увеличить его в два раза с помощью circle.scale(2, 2);. Главное, что наш круг остается объектом, с которым мы можем работать позже.

Processing.js не использует объекты. Функция ellipse ничего не возвращает. Если мы уже нарисовали круг в Processing.js, это уже часть сформированной картинки, как краска на холсте. Это не отдельный объект, который может быть изменен с помощью атрибутов. Чтобы изменить цвет, нам придется нарисовать новый круг поверх прежнего.

Когда мы вызываем fill, это изменяет цвет заливки для всех объектов, которые мы будем рисовать после. После вызова translate и fill, каждая форма будет залита зеленым цветом.

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

Если Processing.js не объектно-ориентированный фреймверк, это не значит, что он хуже. Paper.js и Raphael содержат настройки для всего что вы рисуете, поэтому используют больше памяти, на более сложных анимациях ваше приложение может тормозить.

Processing.js содержит минимум настроек для рисования форм, поэтому использует минимум памяти.

Анимируем рисунки на JavaScript

Вращая круг мы ничего интересного не увидим, поэтому мы создадим квадрат вокруг.

Анимация на javascript

Анимация в Processing.js

Processing.js поддерживает анимацию с предустановленными настройками и функциями отрисовки, как в примере:

float angle = 0.0;
void setup() {
   size(200, 200);
   frameRate(30);
}

void draw() {
   background(#ffffff);
   translate(100, 100);
   fill(#52b755);
   noStroke();
   ellipse(0, 0, 20, 20);

   rotate(angle);
   angle += 0.1;
   noFill();
   stroke(#52b755);
   strokeWeight(2);
   rect(-40, -40, 80, 80);
}

Функция setup вызывается однажды, при старте приложения. Мы указываем frameRate(30), что значит, наша функция будет вызвана 30 раз в секунду, для перерисовки изображения. Так будет создаваться анимация.

Функция draw начинается с заливки фона canvas. Заливаем все белым цветом, другими словами очищаем холст. Как вы помните, здесь мы не можем манипулировать объектами.

Далее мы устанавливаем систему координат 100, 100 с помощью translate. Это значит, все что в квадрате 100 x 100 будет белым. Далее мы будем вращать определенный angle, который возрастает с каждой отрисовкой, что создает впечатление анимации. Последний шаг, нарисовать квадрат с помощью функций fill и rect.

Функция rotate в Processing.js принимает радианы вместо градусов. Поэтому мы увеличиваем на 0,2 с каждой отрисовкой фрейма.

Анимация в Paper.js

Paper.js делает создание простой анимации более удобным способом нежели предыдущий фреймверк.

var r;

function init() {
   var c = new Path.Circle(new Point(100, 100), 10);
   c.fillColor = '#ee2a33';

   var point = new Point(60, 60);
   var size = new Size(80, 80);
   var rectangle = new Rectangle(point, size);
   r = new Path.Rectangle(rectangle);
   r.strokeColor = '#ee2a33';
   r.strokeWidth = 2;
}

function onFrame(event) {
   r.rotate(3);
}

init();

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

Анимация в Raphael

Анимация в Raphael основана на стандартном JavaScript синтаксисе. Мы будем использовать стандартную setInterval функцию.

var paper = Raphael('raphaelAnimation', 200, 200);
var c = paper.ellipse(100, 100, 10, 10);
c.attr({
   'fill': '#00aeef',
   'stroke': '#00aeef'
});

var r = paper.rect(60, 60, 80, 80);
r.attr({
   'stroke-width': 2,
   'stroke': '#00aeef'
});

setInterval(function() {
   r.rotate(6);
}, 33);

Raphael схож с Paper.js, та же объектная модель. Мы имеем квадрат, к которому вызываем функцию rotate. Так мы можем анимировать квадрат с минимальными затратами кода.

Интерактив в Raphael.js, Paper.js, Processing.js

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

Raphael поддерживает модель событий подобно JavaScript, поэтому будет просто отследить клики, перетаскивания и касания. Давайте создадим кликабельный квадратик.

Интерактивный рисунок на javascript

Интерактивность с помощью Raphael

var paper = Raphael('raphaelInteraction', 200, 200);
var r = paper.rect(60, 60, 80, 80);
r.attr({'fill': '#00aeef', 'stroke': '#00aeef'});

var clicked = false;

r.click(function() {
   if (clicked) {
      r.attr({'fill': '#00aeef', 'stroke': '#00aeef'});
   } else {
      r.attr({'fill': '#f00ff0', 'stroke': '#f00ff0'});
   }
   clicked = !clicked;
});

Функция click в Raphael работает так же, как и в jQuery. Вы можете добавить ее к любому событию. Когда мы получили событие клика, нам будет просто изменить цвет квадрата. Raphael имеет больше функций: перетаскивание, наведение и другие функции интерактивности.

Интерактивность с помощью Paper.js

Paper.js управляет интерактивностью разными способами, но все они просты и понятны:

var hitOptions = {
   fill: true,
   tolerance: 5
};

function init() {
   var point = new Point(60, 60);
   var size = new Size(80, 80);
   var rectangle = new Rectangle(point, size);
   r = new Path.Rectangle(rectangle);
   r.fillColor = '#ee2a33';
}

function onMouseUp(event) {
   var hitResult = project.hitTest(event.point, hitOptions);

   if (hitResult && hitResult.item) {
      if (hitResult.item.clicked) {
         hitResult.item.fillColor = '#ee2a33';
      } else {
         hitResult.item.fillColor = '#f00ff0';
      }

      hitResult.item.clicked = !hitResult.item.clicked;
   }
}

init();

Paper.js взаимодействует с мышью с помощью концепта «hit testing», который находит точку в которой установлена мышь и определяет какие объекты лежат под этой точкой. С помощью этого мы можем «уточнять», насколько курсор должен быть близко к квадрату, или что будет происходить по мере приближения к центру квадрата.

Интерактивность с помощью Processing.js

Processing.js определяет нажатие мыши с помощью некоторых приспособлений. Эта библиотека не поддерживает объектных моделей, поэтому приходиться приспосабливаться.

float bx;
float by;
int bs = 20;
boolean bover = false;
boolean clicked = false;

void setup() {
   size(200, 200);
   bx = width/2.0;
   by = height/2.0;
   noStroke();
   fill(#52b755);
   frameRate(10);
}

void draw() {
   background(#ffffff);

   // Проверка на наличие курсора над квадратиком
   if (mouseX > bx-bs && mouseX < bx+bs &&        mouseY > by-bs && mouseY < by+bs) {
      bover = true;
   } else {
      bover = false;
   }

   translate(100, 100);
   rect(-40, -40, 80, 80);
}

void mousePressed() {
   if (bover) {
      if (clicked) {
         fill(#52b755);
      } else {
         fill(#f00ff0);
      }
      clicked = !clicked;
   }
}

После того, как Processing.js нарисовала квадрат, она тут же забыла о нем. Если мы хотим поменять цвет квадрата при нажатии мыши, нам придется все высчитывать самим. Функция draw определяет позицию курсора, если он лежит в области квадрата, мы перерисовываем на новый.

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

Нет абсолютного победителя

Каждый фреймверк имеет свои преимущества. Естественно мы не можем этого увидеть на простых кружочках и квадратиках. Для этого нужны серьезные проекты.

Много примеров графических решений можно найти на официальных сайтах:

http://raphaeljs.com/

http://processingjs.org/exhibition/

http://paperjs.org/examples/

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

Рисуем что-то более сложное на JavaScript

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

Мы создадим шестерни, которые состоят из двух кругов, с зубчиками по внешнему периметру.

Создание шестерни на javascript

Когда все формы имеют один цвет, они выглядят как одна шестерня.

Шестерня на javascript

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

Шестерни на Paper.js

Шестерни на paper.js

Шестерни на Processing.js:

Шестерни на Processing.js

Шестерни на Raphaël:

Шестерни на Raphael.js

На Raphael функция вращения работает по-другому, в отличии от Paper.js и Processing.js. Raphael не поддерживает вращение объектов вокруг определенной точки. Вместо этого, зубчики шестерни рисуются и перерисовываются вокруг центра. Они летают, вместо вращения. Единственным способом заставить шестерню вращаться, является создание единого объекта, как след (path), но это занимает больше времени на разработку, нежели мой способ.

Если кто-то хочет посмотреть, как это работает, кликните на картинки, все это открытый ресурс на GitHub.

На что полагаться? – будущее веб рисования

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

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

SVG в той же ситуации. Браузеры поддерживают его сейчас, но он не получает должного внимания.

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

Вот такая специфика и тенденции веб рисования на javascript. Если есть что добавить или убавить, пишем в комментарии.


Источник материала ...

Дальше: Мини-курс по копирайтингу – бесплатный курс копирайтинга за 20 минут!


Дискуссия по теме     0 Комментариев
Добавить комментарий
Просмотров: 24988