" containsPoint" v 1.7.2和v 2.3.1之间的差异

时间:2018-06-04 00:46:54

标签: javascript fabricjs

我已经回到了在1.7.2版本中完成的FabricJS项目,并且我在v 2.3.1中遇到了一个我无法解决的错误。我想这些版本之间的情况发生了很大的变化。

错误发生在" containsPoint"请拨打下面的代码段:

if (event.e.ctrlKey && canvas.containsPoint(event.e, canvas.backgroundImage)) {
  // code removed for clarity
}

我正在尝试使用画布backgroundImage的rect来测试鼠标事件是否正在发生。

在控制台中,代码失败,Cannot read property 'tl' of null函数调用中出现错误_getImageLines: function(oCoords),因为参数oCoords为空。

v1.7.2代码对oCoords进行了测试,如果它们不存在则设置它们。如果我将该测试修补到v2.3.1中,则不会发生错误。

有人可以解释版本之间的变化或指向我的解释吗?我不想破解v2.3.1。我应该在致电setCoords()之前致电containsPoint()吗?

另外,(为了额外的混淆)虽然2.3.1版本的containsPoint允许传递参数,但在我的使用中,我无法传递参数,因为函数是间接调用的。

(对不起,这太久了!)

版本:" 1.7.2"

   /**
     * Checks if point is inside the object
     * @param {fabric.Point} point Point to check against
     * @return {Boolean} true if point is inside the object
     */
    containsPoint: function(point) {
      if (!this.oCoords) {
        this.setCoords();
      }
      var lines = this._getImageLines(this.oCoords),
          xPoints = this._findCrossPoints(point, lines);

      // if xPoints is odd then point is inside the object
      return (xPoints !== 0 && xPoints % 2 === 1);
    },

版本:' 2.3.1'

containsPoint函数调用页面底部的containsPoint函数。

 /**
     * Checks if point is contained within an area of given object
     * @param {Event} e Event object
     * @param {fabric.Object} target Object to test against
     * @param {Object} [point] x,y object of point coordinates we want to check.
     * @return {Boolean} true if point is contained within an area of given object
     */
    containsPoint: function (e, target, point) {
      // console.log('cp',e, target, point);

      var ignoreZoom = true,
          pointer = point || this.getPointer(e, ignoreZoom),
          xy;

      if (target.group && target.group === this._activeObject && target.group.type === 'activeSelection') {
        xy = this._normalizePointer(target.group, pointer);
      }
      else {
        xy = { x: pointer.x, y: pointer.y };
      }

      // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html
      // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html      
      return (target.containsPoint(xy) || target._findTargetCorner(pointer));
    },
   /**
     * Checks if point is inside the object
     * @param {fabric.Point} point Point to check against
     * @param {Object} [lines] object returned from @method _getImageLines
     * @param {Boolean} [absolute] use coordinates without viewportTransform
     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
     * @return {Boolean} true if point is inside the object
     */
    containsPoint: function(point, lines, absolute, calculate) {

      var lines = lines || this._getImageLines(
            calculate ? this.calcCoords(absolute) : absolute ? this.aCoords : this.oCoords
          ),
          xPoints = this._findCrossPoints(point, lines);

      // if xPoints is odd then point is inside the object
      return (xPoints !== 0 && xPoints % 2 === 1);
    },
 /**
     * Method that returns an object with the object edges in it, given the coordinates of the corners
     * @private
     * @param {Object} oCoords Coordinates of the object corners
     */
    _getImageLines: function(oCoords) {      
      return {
        topline: {
          o: oCoords.tl,
          d: oCoords.tr
        },
        rightline: {
          o: oCoords.tr,
          d: oCoords.br
        },
        bottomline: {
          o: oCoords.br,
          d: oCoords.bl
        },
        leftline: {
          o: oCoords.bl,
          d: oCoords.tl
        }
      };
    },

2 个答案:

答案 0 :(得分:0)

如文档canvas.containsPoint中所述,要求将fabric对象作为第二个参数。如果canvas.backgroundImage不为null,那么它应该有效。并且object.containsPoint需要point,而imageline作为第二个参数。

<强> 样本

&#13;
&#13;
var canvas = new fabric.Canvas('myCanvas',{
 width: 400,
 height: 400
});
var rect = new fabric.Rect({width:100,height:100});
canvas.add(rect);
canvas.on('mouse:down',function(option){
 //if(canvas.containsPoint(option.e,rect)) console.log('inside rect');
 if(rect.containsPoint(option.e)) console.log('inside rect')
})
&#13;
#myCanvas {
  border: 1px solid black;
}
&#13;
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.7/fabric.js"></script>-->
<canvas id="myCanvas" ></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

好的,缩小了范围:

如上所述,Fabric v1.7.2在containsPoint函数中进行了此检查:

   if (!this.oCoords) {
        this.setCoords();
   }

在我修改后的代码中,如果我在调用setCoords()之前进行containsPoint调用,那么就没有错误。我没有遇到任何有关改变的解释,假设它是为了表现。

canvas.backgroundImage.setCoords();

if (event.e.ctrlKey && canvas.containsPoint(event.e, canvas.backgroundImage)) {
  // do some cool stuff
}

v1.7.2和2.3.1之间的另一个区别是canvas.backgroundImage不再具有getWidth()功能。相反,widthheight现在属性。