Pull to refresh

Konva.js — HTML5 2d canvas framework

Reading time 5 min
Views 55K
image

Приветствую. Представляю сообществу проект Konva.js.

Konva.js — это фреймворк, который позволяет работать c canvas 2d в объектном стиле с поддержкой событий.

Кратко список особенностей выглядит так:
  1. Объектное API
  2. Вложенные объекты и «всплытие» событий
  3. Поддержка нескольких слоёв (нескольких canvas элементов)
  4. Кэширование объектов
  5. Поддержка анимаций
  6. Настраиваемый drag&drop
  7. Фильтры
  8. Готовые к использованию объекты, включая прямоугольник, круг, изображение, текст, линия, SVG путь, ..
  9. Простое создание собственных фигур
  10. Событийная архитектура, которая позволяет разработчикам подписываться на события изменений аттрибутов, отрисовки, и так далее
  11. Сериализация и десериализация
  12. Продвинутый поиск с помощью селекторов stage.get('#foo') и layer.get('.bar')
  13. Десктоп и мобильные события
  14. Встроенная подержка HDPI устройств
  15. и еще много разного


Далее подробней рассмотрим возможности фреймворка с примерами кода.

Введение


Всё начинается со Stage, который объеденяет в себе пользовательские слои (Layer).
Каждый слой (Layer) представляет из себя один canvas элемент на странице и может содержать в себе фигуры, группы фигур или группы групп.

Каждый элемент может быть стилизован и трансформирован.

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

Минимальный пример кода [Результат]:

// сначала создаём контейнер
var stage = new Konva.Stage({
      container: 'container',  // индификатор div контейнера
      width: 500,
      height: 500
});

// далее создаём слой
var layer = new Konva.Layer();

// создаём фигуру
var circle = new Konva.Circle({
      x: stage.width() / 2,
      y: stage.height() / 2,
      radius: 70,
      fill: 'red',
      stroke: 'black',
      strokeWidth: 4
});

// добавляем круг на слой
layer.add(circle);

// добавляем слой
stage.add(layer);




Базовые фигуры


Konva.js поддерживает следующие фигуры: прямоугольник (Rect), круг (Circle), овал (Ellipse), линия (Line), изображение (Image), текст (Text), текстовый путь (TextPath), звезда (Star), ярлык (Label), svg путь (Path), правильный многоугольник (RegularPolygon). Так же вы можете создать собственную фигуру:

var triangle = new Konva.Shape({
      drawFunc: function(context) {
        context.beginPath();
        context.moveTo(20, 50);
        context.lineTo(220, 80);
        context.quadraticCurveTo(150, 100, 260, 170);
        context.closePath();

        // специальный метод KonvaJS
        context.fillStrokeShape(this);
      },
      fill: '#00D2FF',
      stroke: 'black',
      strokeWidth: 4
});




Стили


Каждая фигура поддерживает следующие свойства стилей:
  • Закрашивание (fill) — поддерживается сплошной цвет, градиенты и изображения
  • Контур (stroke, strokeWidth)
  • Тень (shadowColor, shadowOffset, shadowOpacity, shadowBlur)
  • Прозрачность (opacity)


var pentagon = new Konva.RegularPolygon({
    x: stage.getWidth() / 2,
    y: stage.getHeight() / 2,
    sides: 5,
    radius: 70,
    fill: 'red',
    stroke: 'black',
    strokeWidth: 4,
    shadowOffsetX : 20,
    shadowOffsetY : 25,
    shadowBlur : 40,
    opacity : 0.5
});


Результат:



События


Используя Konva.js, вы легко можете подписываться на события ввода (click, dblclick, mouseover, tap, dbltap, touchstart и так далее), на события изменения аттрибутов (scaleXChange, fillChange), и на события drag&drop (dragstart, dragmove, dragend).

circle.on('mouseout touchend', function() {
    console.log('user input');
});

circle.on('xChange', function() {
    console.log('position change');
});

circle.on('dragend', function() {
    console.log('drag stopped');
});


Рабочий код + демо

DRAG AND DROP


Фреймоворк имеет встоенную поддержку drag. На данный момент нет поддержки drop событий (drop, dragenter, dragleave, dragover), но они достаточно просто реализуются средствами фреймворка.

Чтобы элемент можно было перетаскивать, достаточно поставить свойства draggable = true.

shape.draggable('true');


При этом вы сможете подписываться на drag&drop события и настраивать ограничения по перемещению. [Демо].

Фильтры


Konva.js включает в себя множество фильтров: размытие, инверсия, сепия, шум и так далее. Полный список доступных фильтров можно посмотреть в API документации по фильтрам.

Пример использования фильтра:

image.cache();
image.filters([Konva.Filters.Invert]);



Анимация


Создавать анимацию можно двумя способами:

1. Через объект «Animation»:

var anim = new Konva.Animation(function(frame) {
    var time = frame.time,
        timeDiff = frame.timeDiff,
        frameRate = frame.frameRate;
    // update stuff
  }, layer);
  anim.start();

[Демо]

2. Через объект «Tween»:

var tween = new Konva.Tween({
        node: rect,
        duration: 1,
        x: 140,
        rotation: Math.PI * 2,
        opacity: 1,
        strokeWidth: 6
});
tween.play();

[Демо]

Селекторы


При построении крупного приложения, крайне удобно использовать поиск по созданным элементам. Konva.js позволяет искать объекты с помощью селекторов, используя методы find (возвращает коллекцию) и findOne (возвращает первый элемент коллекции):

var circle = new Konva.Circle({
        radius: 10,
        fill: 'red',
        id : 'face',
        name : 'red circle'
});
layer.add(circle);
// далее производим поиск

// поиск по типу фигуры
layer.find('Circle'); // все круги

// поиск по id
layer.findOne('#face');

// поиск по имени (аналогия с css классами)
layer.find('.red')


Сериализация и десериализация


Все созданные объекты вы можете сохранить в JSON формат, чтобы, например, сохранить на сервер или локальное хранилище:

var json = stage.toJSON();

А так же создать элементы из JSON:
var json = '{"attrs":{"width":578,"height":200},"className":"Stage","children":[{"attrs":{},"className":"Layer","children":[{"attrs":{"x":100,"y":100,"sides":6,"radius":70,"fill":"red","stroke":"black","strokeWidth":4},"className":"RegularPolygon"}]}]}';

var stage = Konva.Node.create(json, 'container');


Производительность


Konva.js имеет множество инструментов, для значительного повышения производительности.

1. Кеширование позволяет отрисовать некоторый элемент в буфферный canvas и потом рисовать его оттуда. Это может значительно повысить производительность отрисовки сложных объектов как, например, текст или объекты с тенями и контурами.

shape.cache();

[Демо]

2. Работа со слоями. Так как фреймворк поддерживает несколько canvas элементов, вы можете распределять объекты на ваше усмотрение. Допустим, приложение состоит из сложного фона с тектом и нескольких передвигаемый фигур. Логично будет фон и текст перенести на один слой, а фигуры на другой. При этом при обновлении положения фигур, фоновый слой можно не перерисовывать.

[Демо]

Более подробный список советов по повышению производительности доступен здесь: http://konvajs.github.io/docs/performance/All_Performance_Tips.html

Заключение


GitHub: https://github.com/konvajs/konva
Домашняя страница: http://konvajs.github.io/
Документация с примерами: http://konvajs.github.io/docs/
Полное API: http://konvajs.github.io/api/Konva.html

Данный проект является форком известной библиотеки KineticJS, которая автором уже не поддерживается.
Список изменений от последней официальной версии KineticJS можно увидеть здесь.
Tags:
Hubs:
+30
Comments 37
Comments Comments 37

Articles