Javascript 如何在Fabric.js子类中定义事件处理程序?

Javascript 如何在Fabric.js子类中定义事件处理程序?,javascript,fabricjs,Javascript,Fabricjs,我在Fabric.js中有以下子类Rect。它将图像添加到矩形中 var IRect = fabric.util.createClass(fabric.Rect, { type: 'iRect', initialize: function(options) { options || (options = { }); this.callSuper('initialize', options); }, fromObject: func

我在Fabric.js中有以下子类
Rect
。它将图像添加到矩形中

var IRect = fabric.util.createClass(fabric.Rect, {
    type: 'iRect',
    initialize: function(options) {
        options || (options = { });
        this.callSuper('initialize', options);
    },

    fromObject: function (object, callback) {
        return new IRect(object);
    },

    toObject: function() {
        return fabric.util.object.extend(this.callSuper('toObject'), {});
    },

    _render: function(ctx) {
        this.callSuper('_render', ctx);
        var c = document.getElementById('canvas');
        var img = document.getElementById('info');
        c.getContext('2d').drawImage(img, -this.width/2, -this.height/2);

    }
});
我想为
direct
定义特定的事件处理程序。例如,当用户单击一个
direct
,我想发出
alert('hello')
。在我的子类中应该在哪里执行此操作?在定义子类时,如何获取对画布的引用


代码和问题描述可在以下位置找到:

我遇到了相同的问题,并且找到了解决方法。我不确定这是不是正确的方法(我对fabricjs还是很陌生!),但它似乎确实有效,至少在小案例中是如此。基本上,画布不是在initialise中定义的,而是在_render中定义的,因此如果在其中设置事件处理代码,它应该可以工作:)

看起来是这样的:

_render: function(ctx) {
    this.callSuper('_render', ctx);
    // custom rendering code goes here ...

    this.canvas.on('mouse:down', function(e) {
        console.log('mouse down ' + e);
    });
}
我更新了您的JSFIDLE来演示,它将鼠标点击(鼠标:向下事件)记录到控制台(一次点击会触发多个事件,因此警报非常烦人-估计您可以使用cancelbubble或其他方法来停止它,但为了保持简单,示例中没有遇到麻烦)——


最好首先定义一个处理程序,而不是每次调用
\u render
。这会产生太多的事件,这将是生产系统上的一个真正的性能问题。下面是我如何更改上述JSFIDLE javascript代码的:

// -----------------------------------------------------------
// This is my subclass
var IRect = fabric.util.createClass(fabric.Rect, {
    type: 'iRect',
    initialize: function(options) {
        options || (options = { });
        this.callSuper('initialize', options);

        // var canvas = ??? how to get the canvas where this is displayed ?
        // canvas.on('mouse:up', function(){...}
    },

    fromObject: function (object, callback) {
        return new IRect(object);
    },

    toObject: function() {
        return fabric.util.object.extend(this.callSuper('toObject'), {});
    },

    _render: function(ctx) {
        this.callSuper('_render', ctx);
        var img = document.getElementById('info');
        //
        // ctx is the 2d context, no need to get it again from canvas
        //
        ctx.drawImage(img, -this.width/2, -this.height/2);        
    }
});

// -----------------------------------------------------------
// This code will go to my HTML file

var canvas = new fabric.Canvas('canvas');        

// Moved here to make it register once
canvas.on('mouse:down', function(e) {
    console.log('mouse down ' + e);
});

var iRect = new IRect({
    width: 200,
    height: 100,
    left: 100,
    top: 50,
    fill: '#888'
});
canvas.add(iRect);
canvas.renderAll();

这里它是从上一个派生出来的:

因此它适用于fabric.Rects,但它不适用于IText对象(this.canvas不是在调用_render时设置的,似乎如此),所以我找到了一个替代方法,似乎对这两个都适用:)这里fiddle:但基本上,您可以在添加的事件处理程序中执行此操作