javascript - Fabricjs detect mouse over object path - Stack Overflow

Is it possible to capture object:over in Fabric.js only if mouse is on the shape itself and not on the

Is it possible to capture object:over in Fabric.js only if mouse is on the shape itself and not on the imaginary square that contains it?

I have a jsFiddle demo, which contains an U shape. You can see that even if i have the pointer inside the U and not touching any of the lines, it still detects it as a object:over event.

Javascript:

var canvas = new fabric.Canvas("c1", {
    isDrawingMode: false
});

canvas.loadFromJSON(objectsJson, function () {
    canvas.renderAll();
});

canvas.on("object:over", function () {
    console.log("object over");
});
canvas.on("object:out", function () {
    console.log("object out");
});

// code to capture mouse over object while isDrawingMode = false
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);

Is it possible to capture object:over in Fabric.js only if mouse is on the shape itself and not on the imaginary square that contains it?

I have a jsFiddle demo, which contains an U shape. You can see that even if i have the pointer inside the U and not touching any of the lines, it still detects it as a object:over event.

Javascript:

var canvas = new fabric.Canvas("c1", {
    isDrawingMode: false
});

canvas.loadFromJSON(objectsJson, function () {
    canvas.renderAll();
});

canvas.on("object:over", function () {
    console.log("object over");
});
canvas.on("object:out", function () {
    console.log("object out");
});

// code to capture mouse over object while isDrawingMode = false
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);
Share Improve this question edited Feb 3, 2014 at 18:16 kangax 39.2k13 gold badges100 silver badges135 bronze badges asked Feb 2, 2014 at 13:54 CatalinCatalin 11.7k19 gold badges80 silver badges152 bronze badges 3
  • 1 You need perPixelTargetFind and targetFindTolerance (see this demo — fabricjs./per-pixel-drag-drop) – kangax Commented Feb 2, 2014 at 17:00
  • 1 @kangax: Works perfect! although i think targetFindTolerance works only "inside" the element, not also outside .i've set it to a 100 to but still activates only when i "touch" the object. BTW, good gratulations for this awesome project you have made. It just works out-of-box! Awesome – Catalin Commented Feb 3, 2014 at 11:36
  • perfect! glad you like it – kangax Commented Feb 3, 2014 at 18:16
Add a ment  | 

1 Answer 1

Reset to default 2

In fabric.js, for each shape there would created virtual box and when you intersect with this virtual box, the binded event is triggered.

During the create of any shape on fabric.js, this below function create the virtual box by creating various points eg: top left, top right, bottom left, bottom right, middle left, middle right, middle bottom and middle top.

setCoords: function() {
   var strokeWidth = this.strokeWidth > 1 ? this.strokeWidth : 0,
   padding = this.padding,
   theta = degreesToRadians(this.angle);

   this.currentWidth = (this.width + strokeWidth) * this.scaleX + padding * 2;
   this.currentHeight = (this.height + strokeWidth) * this.scaleY + padding * 2;

   // If width is negative, make postive. Fixes path selection issue
   if (this.currentWidth < 0) {
    this.currentWidth = Math.abs(this.currentWidth);
   }

   var _hypotenuse = Math.sqrt(
    Math.pow(this.currentWidth / 2, 2) +
    Math.pow(this.currentHeight / 2, 2));

   var _angle = Math.atan(isFinite(this.currentHeight / this.currentWidth) ? this.currentHeight / this.currentWidth : 0);

   // offset added for rotate and scale actions
   var offsetX = Math.cos(_angle + theta) * _hypotenuse,
      offsetY = Math.sin(_angle + theta) * _hypotenuse,
      sinTh = Math.sin(theta),
      cosTh = Math.cos(theta);

   var coords = this.getCenterPoint();
   var tl = {
    x: coords.x - offsetX,
    y: coords.y - offsetY
   };
   var tr = {
    x: tl.x + (this.currentWidth * cosTh),
    y: tl.y + (this.currentWidth * sinTh)
   };
   var br = {
    x: tr.x - (this.currentHeight * sinTh),
    y: tr.y + (this.currentHeight * cosTh)
   };
   var bl = {
    x: tl.x - (this.currentHeight * sinTh),
    y: tl.y + (this.currentHeight * cosTh)
   };
   var ml = {
    x: tl.x - (this.currentHeight/2 * sinTh),
    y: tl.y + (this.currentHeight/2 * cosTh)
   };
   var mt = {
    x: tl.x + (this.currentWidth/2 * cosTh),
    y: tl.y + (this.currentWidth/2 * sinTh)
   };
   var mr = {
    x: tr.x - (this.currentHeight/2 * sinTh),
    y: tr.y + (this.currentHeight/2 * cosTh)
   };
   var mb = {
    x: bl.x + (this.currentWidth/2 * cosTh),
    y: bl.y + (this.currentWidth/2 * sinTh)
   };
   var mtr = {
    x: mt.x,
    y: mt.y
   };
  this.oCoords = {
    // corners
    tl: tl, tr: tr, br: br, bl: bl,
    // middle
    ml: ml, mt: mt, mr: mr, mb: mb,
    // rotating point
    mtr: mtr
   };

   // set coordinates of the draggable boxes in the corners used to scale/rotate the image
   this._setCornerCoords && this._setCornerCoords();

   return this;
}

So whenever you intersect with any of these 8 points by mouse, the attached event would be fired.

As I know fabric.js, it does not provide the functionality you wanted.

UPDATE:-

As RaraituL said, the pixel detection is possible through perPixelTargetFind(), you can get the example on here. http://fabricjs./per-pixel-drag-drop/

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745674737a4639617.html

相关推荐

  • javascript - Fabricjs detect mouse over object path - Stack Overflow

    Is it possible to capture object:over in Fabric.js only if mouse is on the shape itself and not on the

    5小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信