javascript - 从组中选择对象的问题
问题描述
我目前正在创建自己的具有扩展组功能的自定义组类。首先,我创建了一个可以选择组中对象的功能。该功能的概念是:
- 在画布上单击鼠标时检测鼠标点。
- 基于鼠标点检测分组中的对象。
- 如果在组中找到对象,则激活该对象。
- 如果在组中未找到对象,则激活该组。
- 组中的活动对象具有实线边框,组具有虚线边框。
未修改组时,一切正常。但是,当组进行缩放、旋转和倾斜时,就会出现这些问题:
- 组内对象的选择区域不遵循实际大小。
- 实线边框仍然显示创建对象的初始属性,而不是跟随组的旋转和缩放。
有关更多详细信息,您可以查看下图:
这是组自定义类:
/**
* 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/
问题是为什么在创建对象时,选定对象的选择区域保持不变?
解决方案
fabricJS 中的选择区代码没有考虑分组转换,即使现在 fabricJS 没有理由支持分组选择,这个问题也可以修复。请注意,您可以在不编写自定义代码来查找内部对象的情况下完成您所取得的成就:
https://jsfiddle.net/asturur/wg0mkjv2/3/
fabricJS 支持在组内找到开箱即用的目标,使subTargetCheck
布尔属性能够true
推荐阅读
- r - 如何将R中1到n之间的数字分配给行?
- c - 动态分配是否在堆中存储任何内容?- C语言
- node.js - 节点 bignum 安装失败
- c# - 如果我没有在循环中声明它,为什么 Android MediaPlayer 只播放一次?
- java - Drools 没有按预期工作。未应用规则
- c# - 对用户进行身份验证并从事件中返回数据
- asp.net-core - 什么可能导致关联 cookie 无法在特定设备上返回
- yii2 - 如何调试 Yii2 迁移?
- listview - Xamarin 表单列表视图 - 数据模板到列
- java - ThreadMXBean.getThreadAllocatedBytes(long id)中包含哪些JVM运行时数据区