HTML это основа современного веба. И сегодня, когда пришло
время интерактивных изображений, SVG и Canvas часто являются предметом выбора – Flash уже забыт, Silverlight – редкий единорог который обитает на
окраине Веба, ну и путь еще есть парочку небольших сторонних библотек.
Минусы и плюсы каждого из них хорошо документированы, но по сути, SVG лучше подходит для создания и
обработки интеракивных элементов. Это связано с тем, что SVG описывается векторным XML-форматом, и
когда изображение загружено на странице с использованием тэга <svg>, каждый
элемент в нем становится полноценным элементов SVG DOM.
В данной статье, я представлю вам GraphicsJS, новую и мощную JavaScript библиотеку для рисования с открытым
исходным кодом, которая базируется на SVG (с поддержкой VML для старых версий IE). Я начну с
короткого введения, в котором расскажу о базовых принципах, а после этого продемонстрирую
функциональность библиотеки с помощью двух коротких, но тем не менее
впечатляющих примеров: первый – это исскуство, в то время как второй
иллюстрирует как программно создавать игру убийцу времени менее чем за 50 строк
кода.
Почему GraphicsJS
Существует много библиотек, которые предназначены
для работы с SVG: Raphaël, Snap.svg, и BonsaiJS это одни из лучших. Каждая
из них имеет свои преимущства и недостатки, но сравнивать их в данной статье я
не буду. Вместо этого я опишу GraphicsJS,
поэтому давайте я объясню что делает библиотеку хорошей и особенной.
Во первых, GraphicsJS легковесная и имеет очень
гибкое JavaScript API.
Оно реализует большое разнообразие логики для работы с текстом, имеет отличный
виртуальный DOM – отделенный от HTML DOM реализации конкретного браузера.
Во-вторых, это новая библиотека JavaScript с
открытым исходным кодом, которую совсем
недавно выпустил AnyChart, один из лучших
разработчиков в сфере визуализации интерактивных данных. Данный разработчик
использовал GaphicsJS для отображения диаграмм в своих коммерческих продуктах на
протяжении как минимум последних трех лет (со времен появления AnyChart 7.0). Таким образом,
данная библиотека хорошо протестирована в реальных условиях (Отречение: я ни в
коем случае не являюсь ни R&D в AnyChart ни
главный разработчик GaphicsJS).
В-третьих, в отличие от прочих библиотек AnyChart, библиотека GraphicsJS может
использоваться бесплатно в коммерческих и некомерческих проектах. Она доступна
в GitHub под лицензией Apache.
В четвертых, работает с любыми браузерами, и
поддерживает IE 6.0+, Safari 3.0+, Firefox 3.0+ и Opera 9.5+. Она использует VML в
старых версиях IE и SVG во всех остальных браузерах.
Наконец, GraphicsJS позволяет комбинировать
графику и анимацию для получения лучшего эффекта. Посмотрите на главную
галерею, которая демонстрирует возможности анимационного
костра, вращающейся
галактики, падающего
дождя, процедуры
генерации листьев, игры
пятниашки и многое другое. GraphicsJS содержит много других примеров, всеобъемлющей документации и справочник по API.
Основы GraphicsJS
Для того что бы начать использовать библиотеку нужно добваить на ссылку на нее и создать блочный элемент HTML для рисования:<html lang="en">
<head>
<meta charset="utf-8" />
<title>GraphicsJS Basic Example</title>
</head>
<body>
<div id="stage-container" style="width: 400px; height: 375px;"></div>
<script src="https://cdn.anychart.com/js/latest/graphics.min.js"></script>
<script>
// GraphicsJS code here
</script>
</body>
</html>
После этого нужно создать стейдж и нарисовать что-нибудь, например прямоугольник или круг или другую фигуру:
// create a stage
varstage=acgraph.create('stage-container');
// draw a rectangle
varЗдесь представлен пример CodePen в котором мы идем немного дальше и рисуем символ Дары смерти.stage.rect(25,50,350,300);
Наш Первый Шедевр
Fill, Stroke и текстурная заливка
Любая фигура может быть разукрашена с
использованием fill settings и stroke settings. Любой объект
имеет границу, но только фигуры и закрытые контуры имеют заливку. Настройки
контуров и заливки очень разнообразны, вы можете использовать даже линейный и
круговой градиенты и для контуров и для заливок. Кроме того линии могут быть
прерывистыми, заливка может базироваться на некотором изображении с
использованием наскольких плиточных режимов. Но все это весьма стандартно, что
можно найти и в других библиотеках.Но есть функциональность которая делает GraphicsJS уникальной
библиотекой – это штриховка
и узор заливки, которая позволяет не только использовать доступные 32 вида
штриховок, но также и легко создавать свои новые виды.
Теперь давайте посмотрим как именно это делается!
Мы нарисуем мальенкую картинку с человечком стоящим возле дома, и после этого
улучшим эту картику с помощью различных видов заливки. Для простоты картинку
сделаем немного наивной
(попытаемся не попасть в арт-брют).
// create a stage
varstage=acgraph.create('stage-container');
// draw the frame
varframe=stage.rect(25,50,350,300);
// draw the house
varwalls=stage.rect(50,250,200,100);
varroof=stage.path()
.moveTo(50,250)
.lineTo(150,180)
.lineTo(250,250)
.close();
// draw a man
varhead=stage.circle(330,280,10);
varneck=stage.path().moveTo(330,290).lineTo(330,300);
varkilt=stage.triangleUp(330,320,20);
varrightLeg=stage.path().moveTo(320,330).lineTo(320,340);
varleftLeg=stage.path().moveTo(340,330).lineTo(340,340);
Как вы заметили мы используем переменные – все
методы которые что-то рисуют на стейдже возвращают ссылку на созданный объект,
и эта ссылка может быть использована для изменения или удаления объекта.
Также, обратите внимание на то как формируется
цепочка, которая в GraphicsJS используется повсеместно и помоает сократить код.
Формирование цепочки вызовов (например
stage.path().moveTo(320, 330).lineTo(320, 340);) следует использовать
аккуратно, но оно делает код более компактным и легким в понимании.
Теперь давайте эту разукрашку передадим ребенку и
позволим ему ее разукрасить. Потому что даже ребенок способен совладать с
подобной техникой:
// color the picture
// fancy frame
frame.stroke(["red","green","blue"],2,"2 2 2");
// brick walls
walls.fill(acgraph.hatchFill('horizontalbrick'));
// straw roof
roof.fill("#e4d96f");
// plaid kilt
kilt.fill(acgraph.hatchFill('plaid'));
Здесь показано как наш пример выглядит сейчас.
Далее возмем картику с горцем в килте, котрый
стоит возле каменного замка с соломенной крышей. Мы можем ударится в крайности
и сказать что это действительно произведение искусства, авторские права на
который мы хотим защитить. Давайте это сделаем с кастомным паттерном заливки
постреном в виде текста.
// 169 is a char code of the copyright symbol
vartext=acgraph.text().text(String.fromCharCode(169)).opacity(0.2);
varpattern_font=stage.pattern(text.getBounds());
pattern_font.addChild(text);
// fill the whole image with the pattern
frame.fill(pattern_font);
Как вы видите это очень просто: создаете
экземпляр текстового
объекта, после формируете паттерн
на стедже и добавляете текст в паттерн.
Создание художественной игры Убийцы-времени за менее чем 50 строк кода
В следующей части статьи, я хочу показать как создать Кликер Печенек – игру на GraphicsJS за
менее чем 50 строк кода.
Название игры “Дворник на ветру” – и игрок
становится дворником в ветренную погоду. В игре используется код с примера
с падающими листьями с галереи GraphicsJS.
Вы можете посмотреть на завершенную игру здесь
(или дочитать до
конца статью).
Слои, zIndex и Виртуальный DOM
Мы начнем с создания стейджа ( как и раньше),
потом объявим несколько переменных:
// create stage
varstage=acgraph.create("stage-container");
// color palettes for leaves
varpalette_fill=['#5f8c3f','#cb9226','#515523','#f2ad33','#8b0f01'];
varpalette_stroke=['#43622c','#8e661b','#393b19','#a97924','#610b01'];
// counter
varleavesCounter=0;
Для этой игры мы будем использовать Слой – объект,
предназначенный для групировки элементов в GraphicsJS. Элементы должны группироваться если вы хотите
применить одни и теже изменения для них, например трансформацию. Вы можете
изменить слои когда находитесь в приостановленном режиме (подробнее об этом
чуть позже), который увеличивает
производительность и пользовательский интерфейс.
В этом демо мы используем функциональность слоев
для того что бы сгруппировать листья и иизбежать их перекрытия метками (которые
показывают, сколько было обработано). Для того что бы это сделать мы создали
метку и после этого вызвали метод
stage.layer,
который привязывает слой к стейджу. Мы присвоили этому слою более низкий zIndex, чем у метки.// create a label to count leaves
varcounterLabel=stage.text(10,10,"Swiped: 0",{fontSize:20});
// a layer for the leaves
vargameLayer=stage.layer().zIndex(counterLabel.zIndex()-1);
После этого, нет большой разницы сколько листьев
мы создаем на сслое, они в любом случае не смогут перекрыть метку.
Трансформации
Далее, давайте добавим функциою рисования
листьев. Это позволит нам познакомится с API для трансформаций в GraphicsJS, которое позволяет двигать,
масштабировать, поворачивать и сдвигать и элементы и группы элементов. Когда
трансформации используются со слоями и витруальным DOM – это
становиться очень мощным инструментом.
functiondrawLeaf(x,y){
// choose a random color from a palette
varindex=Math.floor(Math.random()*5);
varfill=palette_fill[index];
varstroke=palette_stroke[index];
// generate random scaling factor and rotation angle
varscale=Math.round(Math.random()*30)/10+1;
varangle=Math.round(Math.random()*360*100)/100;
// create a new path (leaf)
varpath=acgraph.path();
// color and draw a leaf
path.fill(fill).stroke(stroke,1,'none','round','round');
varsize=18;
path.moveTo(x,y)
.curveTo(x+size/2,y-size/2,x+3*size/4,y+size/4,x+size,y)
.curveTo(x+3*size/4,y+size/3,x+size/3,y+size/3,x,y);
// apply random transformations
path.scale(scale,scale,x,y).rotate(angle,x,y);
returnpath;
};
Вы видите, что любой контур создается одинаковым
образом, но после этого подвергается трансформации. В результате получается
очень интересный рандомный паттерн для листьев.
Обработка событий
Любой объект, стейдж или слой в GraphicsJS может
обрабатывать события. Полный список поддерживаемых событий доступен в EventType API. У стейджа есть четыре
специальные события для контроля отрисовки.
В данном примере мы используем слушатели событий,
которые подсоеденены к объектам листьев. Таким образом исчезают один за одним,
когда пользователь наводит курсор мыши. Для того, что бы этого добиться,
добавте следующий код в конец функции
drawLeaves перед
вызовом return.path.listen("mouseover",function(){
path.remove();
counterLabel.text("Swiped: "+leavesCounter++);
if(gameLayer.numChildren()<200)shakeTree(300);
});
Here we can also see that
we are using the layer to count leaves. if(gameLayer.numChildren()<200)shakeTree(300);
Обратите внимание, что мы не храним общее
количество листьев. Поскольку листья – это контуры, которые добавляются и
удаляются с конкретного слоя, то это позволяет отслеживать сколько дочерних
элементов он имеет (и сколько листьев осталось).
GraphicsJS предоставляет virtual DOM,абстракцию HTML DOM, легковесную и не
связанную с реализаций SVG\VML конкретного
браузера. Это полезно для того что бы делать много клевых вещей, таких как
отслеживание всех объектов на слое, применения трансформаций для групп и
оптимизации отрисовки с помощью методов, которые позволяют нам отслеживать и
контролировать процесс отрисовки.
Оптимизация производительности
Витруальный DOM вместе с обработчиками событий позволяют пользовтелям GrasphicsJS контролировать
отрисовку. Статья по
производительности может дать вам идею как это можно применять.
При генерации листьев в нашей игре, мы должны
приостановить отрисовку когда добавляем новые листья и возобновить после того
как наши изменения были сделаны.
functionshakeTree(n){
stage.suspend();// suspend rendering
for(vari=0;i<n;i++){
varx=Math.random()*stage.width()/2+50;
vary=Math.random()*stage.height()/2+50;
gameLayer.addChild(drawLeaf(x,y));// add a leaf
}
stage.resume();// resume rendering
}
Благодаря такому способу, листья появляются почти
мгновенно.
Наконец, после того как все сделано, вызовем
shakeTree().// shake a tree for the first time
shakeTree(500);
Выводы
Движение к HTML5 изменило веб. Когда речь заходит о современных веб
приложениях или даже о простых сайтах, мы часто сталкиваемся с задачми по
работе с изображениями. Невозможно найти решение которое работает одинаково
хорошо в различных ситуациях, но мы должны присмотреться к GraphicsJS. Это библиотека с отрытым
исходным кодом, быстрая с изумительной поддержкой браузеров и большим
количеством различных возможностей, которые делают ее интересной, удобной и
разумеется полезной.
Я буду рад услышать любые отзывы о библиотеке в
коментариях к статье. Вы используете ее уже? А будете использовать для новых
проектов? Я был бы рад услышать почему да или почему нет. В настоящий момент я
работаю над списком JavaScript библиотек для рисования и статьей, в которой буду сравнивать
их. Поэтому сообщайте мне обо всех библиотеках, которые вы хотите увидеть в
моем обзоре.
Источник: https://www.sitepoint.com/introducing-graphicsjs-a-powerful-lightweight-graphics-library/
Комментариев нет:
Отправить комментарий