Fabricjs检测对象路径上的鼠标

时间:2014-02-02 13:54:21

标签: javascript jquery html5-canvas fabricjs

只有当鼠标位于形状本身而不是包含它的假想方块上时,是否有可能在Fabric.js中捕获object:over

我有jsFiddle demo,其中包含U形。您可以看到,即使我在U中有指针并且未触及任何行,它仍会将其检测为object:over事件。

enter image description here

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

1 个答案:

答案 0 :(得分:2)

在每个形状的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;
}

因此,只要您通过鼠标与这8个点中的任何一个相交,就会触发附加事件。

据我所知fabric.js,它不提供您想要的功能。

<强>更新: -

正如RaraituL所说,可以通过perPixelTargetFind()进行像素检测,你可以在这里得到例子。 http://fabricjs.com/per-pixel-drag-drop/