Search code examples
javascriptbackbone.jsfabricjsmarionette

How to pass a UI element to a new fabric canvas within a Marionette ItemView


I want to use Fabric.js and Marionette.js v2.4.7.

I have error

Cannot create property 'style' on string 'constructor'

I'm trying to use this.ui.canva but have error

Cannot set property 'userSelect' of undefined

ItemView

define([
    'app',
    'marionette',
    'backbone',
    'underscore',
    'pace',
    'text!templates/constructor/index.ejs',
    'fabric'
], function (App, Marionette, Backbone, _, pace, constructorTmpl, fabric) {
    'use strict';

    return Marionette.ItemView.extend({
        template: _.template(constructorTmpl),
        ui: {
            canva: '#constructor'
        },
        onRender: function () {
            var canvas = new fabric.Canvas('constructor');
        }
    });
});

index.ejs

<canvas id="constructor" width="300" height="300"></canvas>

Solution

  • Since the view's element is not in the DOM yet, fabric can't globally find the element with id constructor.

    But the element already exist in memory inside the view and you can use it. fabric.Canvas can take a DOM element instead of a string.

    In Marionette versions before v3, the ItemView takes care of calling bindUIElements and they are made available directly in the ui hash.

    onRender: function () {
        var canvas = new fabric.Canvas(this.ui.canva[0]);
    }
    

    In Marionette v3 and up

    Note: From Marionette v3.x, Marionette.View replaces Marionette.LayoutView and Marionette.ItemView.

    Use getUI view function to get the jQuery object of the UI element.

    onRender: function () {
        var canvas = new fabric.Canvas(this.getUI('canva')[0]);
    }