我已经回到了在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
}
};
},
答案 0 :(得分:0)
如文档canvas.containsPoint中所述,要求将fabric对象作为第二个参数。如果canvas.backgroundImage
不为null,那么它应该有效。并且object.containsPoint需要point,而imageline作为第二个参数。
<强> 样本 强>
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;
答案 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()
功能。相反,width
和height
现在属性。