简体   繁体   English

Fabricjs检测对象路径上的鼠标

[英]Fabricjs detect mouse over object path

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? 是否有可能捕获object:over仅当鼠标位于形状本身而不是包含它的假想方块上时才在Fabric.js中捕获?

I have a jsFiddle demo , which contains an U shape. 我有一个jsFiddle演示 ,它包含一个U形。 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. 你可以看到,即使我有指针在U内并且没有触及任何一条线,它仍然会将其检测为一个object:over event。

在此输入图像描述

Javascript: 使用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);

In fabric.js, for each shape there would created virtual box and when you intersect with this virtual box, the binded event is triggered. fabric.js,对于每个形状,都会创建虚拟框,当您与此虚拟框相交时,会触发绑定事件。

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. fabric.js,上创建任何形状fabric.js,此功能通过创建各种点来创建虚拟框,例如: 左上,右上,左下,右下,中左,中右,中下和中上。

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. 因此,只要您通过鼠标与这8个点中的任何一个相交,就会触发附加事件。

As I know fabric.js , it does not provide the functionality you wanted. 据我所知fabric.js ,它不提供你想要的功能。

UPDATE:- 更新: -

As RaraituL said, the pixel detection is possible through perPixelTargetFind() , you can get the example on here. 正如RaraituL所说,通过perPixelTargetFind()可以进行像素检测,你可以在这里得到例子。 http://fabricjs.com/per-pixel-drag-drop/ http://fabricjs.com/per-pixel-drag-drop/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM