Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fabric.js - Ending free drawing mode while mouse is moving

I have an application that allows the user to draw in a fabric canvas for a limited period of time. After the time ends, I would like to end the drawing mode and save the drawing made as an image.

My problem is that if the time ends while the user is still drawing (dragging the mouse), the drawing will disappear (after clicking on the canvas again).

The below fiddle example shows the application I made, and the steps to produce the problem are:

  1. Run the fiddle, and start drawing immediately.
  2. After 3 seconds the timeout event will occur and the free drawing mode will be ended. And the drawing will stop.
  3. Click on the canvas again and drag the mouse.
  4. The drawing will disappear.

Code example:

var canvas = new fabric.Canvas("c",{backgroundColor : "#fff"});
canvas.isDrawingMode = true;
canvas.freeDrawingBrush.color = "green";
canvas.freeDrawingBrush.width = 4;

setTimeout(stop_drawing, 3000);

function stop_drawing() {
    canvas.isDrawingMode = false;
}

Fiddle example:

https://jsfiddle.net/usaadi/808x5d20/1/

like image 711
Osama Avatar asked Oct 15 '25 04:10

Osama


1 Answers

You could emulate what happens in the library:

_onMouseUpInDrawingMode: function(e) {
  this._isCurrentlyDrawing = false;
  if (this.clipTo) {
    this.contextTop.restore();
  }
  this.freeDrawingBrush.onMouseUp();
  this._handleEvent(e, 'up');
},

In your case, you have just to fire onMouseUp event, so your function stop_drawing will be:

function stop_drawing() {
  canvas.isDrawingMode = false;
  canvas.freeDrawingBrush.onMouseUp();

}

in our case onMouseUp will be:

/**
* Invoked on mouse up
*/
onMouseUp: function() {
  this._finalizeAndAddPath();
},

let's see how it works _finalizeAndAddPath:

     /**
     * On mouseup after drawing the path on contextTop canvas
     * we use the points captured to create an new fabric path object
     * and add it to the fabric canvas.
     */
    _finalizeAndAddPath: function() {
      var ctx = this.canvas.contextTop;
      ctx.closePath();

      var pathData = this.convertPointsToSVGPath(this._points).join('');
      if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') {
        // do not create 0 width/height paths, as they are
        // rendered inconsistently across browsers
        // Firefox 4, for example, renders a dot,
        // whereas Chrome 10 renders nothing
        this.canvas.renderAll();
        return;
      }

      var path = this.createPath(pathData);

      this.canvas.add(path);
      path.setCoords();

      this.canvas.clearContext(this.canvas.contextTop);
      this._resetShadow();
      this.canvas.renderAll();

      // fire event 'path' created
      this.canvas.fire('path:created', { path: path });
    }

at this point the drawn path has already been added to the canvas.

I have updated your snippet here if you want to take a look at the code below...

all the best

var canvas = new fabric.Canvas("c", {
  backgroundColor: "#fff"
});
canvas.isDrawingMode = true;
canvas.freeDrawingBrush.color = "green";
canvas.freeDrawingBrush.width = 4;

setTimeout(stop_drawing, 3000);

function stop_drawing() {
  canvas.isDrawingMode = false;
  canvas.freeDrawingBrush.onMouseUp();

}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="500" height="500" style="border:1px solid #ccc"></canvas>
like image 117
alessandro Avatar answered Oct 19 '25 14:10

alessandro