Использование Backbone.js при работе c html5 canvas

    1. Описание задачи


    Разрабатывая крупное mind map приложение, мы выбрали Backbone в качестве основной библиотеки построения приложения. При этом карта ума рисуется через canvas элемент с помощью различных примитивов. Мы выбрали библиотеку KineticJS для работы с canvas, так как она отлично поддерживает работу с событиями для объектов на холсте.

    Чтобы соответствовать архитектуре Backbone все работа с canvas (точнее с экземплярами объектов KineticJS) происходила в экземплярах Backbone.View:

    var Node = Backbone.View.extend({
       initialize : function(params) {
            this.layer = params.layer;
            this.node = this.el();
            this.bindEvents();
        },
        el : function(){
            var rect = new Kinetic.Rect({
              x : 100,
              y : 100,
              width : 50,
              height : 50,
              fill : 'green',
              id : 'rect'
            });
            return rect;
      },
      bindEvents: function() {
             this.node.on('click', function(){
                 console.log("on rectangle clicked");
              }
              // etc ...
       }
    });
    


    2. Проблема


    Но Backbone View спроектирован для работы с DOM элементами, и при таком подходе генерировал не нужные нам div объекты и объявлять события в декларативном стиле (http://backbonejs.org/#View-delegateEvents) тоже не получалось.

    3. Решение.


    Был написан плагин Backbone.KineticView, который позволял работать с объектами на canvas (через KineticJS) в таком же стиле, как и обычный Backbone.View работает с DOM.

    Пример того, как теперь выглядит код:

        var MyView = Backbone.KineticView.extend({
          initialize : function(params) {
            this.layer = params.layer;
          },
          nodeType : 'Rect',
          attributes : {
              x : 100,
              y : 100,
              width : 50,
              height : 50,
              fill : 'green',
              id : 'rect'
          },
          // setup events
          events : {
            'click' : function(){
              console.log("on rectangle clicked");
            }
          }
          render : function(){
            this.layer.add(this.el);
            this.layer.draw();
          }
        });
    
    view = new MyView({layer:layer});
    view.render();
    


    Данный плагин почти полностью повторяет функционал Backbone.View, но только для KineticJS объектов. По аналогии были адаптированы тесты от Backbone.View.

    Чуть более сложный живой пример можно посмотреть здесь: http://jsbin.com/fekex/4/edit
    Код плагина: https://github.com/slash-system/backbone.kineticview

    Наверно аналогичные решения можно легко построить для подобных canvas библиотек: Easeljs, FabricJS и т.д. Кто-нибудь уже решал такую задачу?
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 5

      0
      Backbone может генерировать любой элемент, который указан в переменной tagName, с указанными атрибутами. А может не генерировать ничего вовсе, если передавать ссылку на кготовый элемент в переменной в конструктор в переменной el, так что он достаточно гибок.
        0
        Решал подобную задачу для fabric.js: на самом деле всё просто. Т.к. холст является HTML DOM Element, его можно использовать в качестве tagName, как уже сказал e_asphyx. Соответственно, вы создаете представление, где указываете tagName: «canvas», а в методе initialize создаете экземпляр fabric.js, вешаетесь на события библиотеки и баблите наверх. Получается, чтобы использовать библиотеку, вам достаточно подключить ваше представление. Если нужна помощь — пишите в лс.
          +1
          Да, действительно. Чтобы создать «общее» представление для Stage (Kinetic.Stage, fabric.Canvas, createjs.Stage) достаточно удобно использовать Backbone.View, передав в него ссылку на готовый canvas элемент в параметр el (спасибо e_asphyx). Если же работать с представлениями, которые не работают напрямую с canvas, а работают с объектами библиотеки, то сторонний плагин становится гораздо удобней. Передавать ссылку на canvas элемент в каждый View, который с canvas не работает, выглядит, на мой взгляд, как костыль.
          0
          Прости, это статья про то, как наследовать 1 класс в backbone?
          Странно видеть такое на хабре, честно говоря.
            0
            Я в чем то не прав? Эта статья хоть немного уходит за пределы стандартной документации?
            Что то я пропустил посмотреть сам плагин.
            Тем не менее мне кажется странным использовать инструмент, предназначенный для одного, для другого. Почему бы не посмотреть в сторону другого фреймворка / обёртки для решения задачи?

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

          Самое читаемое