Skip to content

Working with events

琚致远 edited this page May 28, 2020 · 34 revisions

Note

The events listed below were out of date, please refer to http://fabricjs.com/v2-breaking-changes-2.

Introduction

Fabric exposes a number of events to allow for extensibility and decoupled functionality. To subscribe to events of a particular canvas instance, use its on method. If you wish to fire an event on a canvas, use its trigger method. The same goes for instances of fabric.Object.

Events handled by canvas

Note that events are always scoped per canvas instance, so they don't conflict with those of others. Clicking on canvas triggers "mouse:down" and "mouse:up" on that exact canvas instance; clicking on another canvas fires events on that canvas instance. Take a look at the examples below to see how you register to canvas related events.

The list of currently-existing events is as follows:

General

  • after:render — fired continuously after each frame is rendered
  • before:render — fired before each frame is rendered
  • canvas:cleared — fired after a call to canvas.clear()

Mouse related

  • mouse:over
  • mouse:out
  • mouse:down — fired when mousedown event occurred on canvas
  • mouse:up — fired when mouseup event occurred on canvas
  • mouse:move — fired when the mouse is moving over the canvas
  • mouse:wheel - fired when using the scroll wheel

Object related

  • object:added — fired after object has been added
  • object:modified — fired after object is modified (moved, scaled, rotated)
  • object:moving — fired continuously during object movement
  • object:over — fired when mouse is over object (see example below)
  • object:out — fired when mouse is moved away from object (see example below)
  • object:removed — fired when object has been removed
  • object:rotating — fired continuously during object rotating
  • object:scaling — fired continuously during object scaling
  • object:selected — fired when object is selected

Path related

  • path:created — fired when (free-drawn) path is created

Selection related

  • before:selection:cleared — fired before selection is cleared (before active group is destroyed)
  • selection:cleared — fired after selection is cleared (after active group is destroyed)
  • selection:created — fired after selection is created (after active group is created)

Text related

  • text:editing:entered
  • text:editing:exited
  • text:selection:changed
  • text:changed

Events handled by objects

General

  • added
  • removed

Mouse related

  • mousedown
  • mouseup
  • mouseover
  • mouseout

Modification related

  • modified
  • rotating
  • scaling
  • moving
  • skewing

Selection related

  • deselected
  • selected

Text related

  • editing:entered
  • editing:exited
  • selection:changed — cursor selection in iText has changed
  • changed
  • dblclick
  • tripleclick

Demos and Examples

//EXAMPLE: How to register to canvas related events

//instance of fabric.Canvas
var canvas = new fabric.Canvas('my-canvas');

//handler for moving objects on canvas
var moveHandler = function (evt) {
    var movingObject = evt.target;
    console.log(movingObject.get('left'), movingObject.get('top'));
};

//handler for done modifying objects on canvas
var modifiedHandler = function (evt) {
    var modifiedObject = evt.target;
    console.log(modifiedObject.get('left'), modifiedObject.get('top'));
};

var customEvtHandler = function (evt) {
    console.log("I was triggered by a custom event.");
};

//either you register "event by event"
canvas.on('object:moving', moveHandler);
canvas.on('object:modified', modifiedHandler);
canvas.on('custom:event', customEvtHandler);

//or you register with key/value pairs
canvas.on({
    'object:moving' : moveHandler,
    'object:modified' : modifiedHandler,
    'custom:event' : customEvtHandler
});

//trigger our custom event handler
canvas.trigger("custom:event", {...});
// piggyback on `canvas.findTarget`, to fire "object:over" and "object:out" events
canvas.findTarget = (function(originalFn) {
  return function() {
    var target = originalFn.apply(this, arguments);
    if (target) {
      if (this._hoveredTarget !== target) {
        canvas.fire('object:over', { target: target });
        if (this._hoveredTarget) {
          canvas.fire('object:out', { target: this._hoveredTarget });
        }
        this._hoveredTarget = target;
      }
    }
    else if (this._hoveredTarget) {
      canvas.fire('object:out', { target: this._hoveredTarget });
      this._hoveredTarget = null;
    }
    return target;
  };
})(canvas.findTarget);
//piggyback on mouseup for object mouseup
main.canvas._onMouseUp = (function(originalFn) {
	return function(e) {
		_this = main.canvas;
		_this.__onMouseUp(e);
		if (_this.getActiveObject()) {
			_this.fire('object:mouseup', { target: _this.getActiveObject() }, e);	
		}
        	removeListener(fabric.document, 'mouseup', _this._onMouseUp);
        	fabric.isTouchSupported && removeListener(fabric.document, 'touchend', _this._onMouseUp);
       		removeListener(fabric.document, 'mousemove', _this._onMouseMove);
        	fabric.isTouchSupported && removeListener(fabric.document, 'touchmove', _this._onMouseMove);
        	addListener(_this.upperCanvasEl, 'mousemove', _this._onMouseMove);
       		fabric.isTouchSupported && addListener(_this.upperCanvasEl, 'touchmove', _this._onMouseMove);
	};
})(main.canvas.setActiveObject);