【发布时间】:2020-09-22 23:22:56
【问题描述】:
我目前正在创建自己的具有扩展组功能的自定义组类。首先,我创建了一个可以选择组中对象的功能。该功能的概念是:
- 在画布上单击鼠标时检测鼠标点。
- 根据鼠标点检测分组中的对象。
- 如果在组中找到对象,请激活该对象。
- 如果在组中找不到对象,则激活组。
- 组中的活动对象具有实线边框,组具有虚线边框。
当组没有被修改时,一切都运行良好。但是,当组进行缩放、旋转和倾斜时,就会出现这些问题:
- 组内对象的选择区域不按照实际大小。
- 实心边框仍显示创建对象时的初始属性,而不是跟随组的旋转和缩放。
更多详情可以看下图:
这是组自定义类:
/**
* GroupExtended class
* @extends fabric.Group
* @todo preserve object stacking
* @todo fix bug object coords on group scaling
*/
var GroupExtended = fabric.util.createClass(fabric.Group, {
/**
* Type of an object
* @type String
* @default
*/
type: "group-extended",
/**
* When set to `false`, object's controlling borders are not rendered
* @type Boolean
* @default
*/
hasBorders: true,
/**
* Array specifying dash pattern of an object's borders (hasBorder must be true)
* @type Array
* @default
*/
borderDashArray: [5, 5],
/**
* Selected object
* @type fabric.Object
*/
_selectedObject: null,
/**
* Remove solid border from selected object
*/
_removeSelectedBorder: function () {
this.canvas.clearContext(this.canvas.contextTop);
},
/**
* Show solid border from selected object
*/
_showSelectedBorder: function () {
this._removeSelectedBorder();
this._selectedObject &&
this._selectedObject._renderControls(this.canvas.contextTop, {
hasControls: false,
});
},
/**
* Constructor
* @param {Object} objects Group objects
* @param {Object} [options] Options object
* @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already.
* @return {Object} thisArg
*/
initialize: function (objects, options, isAlreadyGrouped) {
this.callSuper("initialize", objects, options, isAlreadyGrouped);
this.on({
moving: this._showSelectedBorder,
deselected: this._removeSelectedBorder,
});
},
/**
* Get selected object based on mouse point.
* Return detected object or
* most top of objects if more than one object detected in mouse point or
* null if mouse point refer to empty area in group.
* @param {Object} point object with "x" and "y" number values
* @return {fabric.Object} selected object
*/
getSelectedObjectInGroup: function (point) {
// reset last known selected object
this._selectedObject = null;
this._removeSelectedBorder();
this.forEachObject(
function (obj) {
var matrixPoint = obj.calcTransformMatrix();
var center = {
x: matrixPoint[4],
y: matrixPoint[5],
};
var thisPos = {
xStart: center.x - obj.width / 2,
xEnd: center.x + obj.width / 2,
yStart: center.y - obj.height / 2,
yEnd: center.y + obj.height / 2,
};
if (point.x >= thisPos.xStart && point.x <= thisPos.xEnd) {
if (point.y >= thisPos.yStart && point.y <= thisPos.yEnd) {
this._selectedObject = obj;
this._showSelectedBorder();
}
}
}.bind(this)
);
return this._selectedObject;
},
});
jsfiddle 链接:https://jsfiddle.net/clngkusnd/pa5dzLm2/
问题是为什么在创建对象时,选定对象的选择区域保持不变?
【问题讨论】:
标签: javascript html5-canvas fabricjs