从组中选择对象的问题

问题描述 投票:0回答:1

我当前正在创建具有扩展组功能的自定义组类。首先,我创建了一个功能,可以选择组中的对象。该功能的概念是:

  1. 在画布上单击鼠标时检测鼠标点。
  2. 基于鼠标点检测组中的对象。
  3. 如果在组中找到对象,请激活该对象。
  4. 如果在组中找不到对象,则激活该组。
  5. 组中的活动对象具有实线边框,并且组具有虚线边框。

如果未修改组,一切都将完美工作。但是,当组缩放,旋转和倾斜时,会出现以下问题:

  1. 组中对象的选择区域不符合实际大小。
  2. 实线边框仍然显示创建对象的初始属性,而不遵循组的旋转和缩放。

有关更多详细信息,请参见下面的图像:

problem and expected result

这是组自定义类:

/**
 * 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
1个回答
0
投票

fabricJS中的选择区代码不考虑组转换,即使fabricJS目前没有理由支持组选择,也可以解决此问题。请注意,无需编写自定义代码即可查找内部对象即可完成所获得的目标:

https://jsfiddle.net/asturur/wg0mkjv2/3/

fabricJS支持在组内找到目标,将subTargetCheck布尔属性设为true

© www.soinside.com 2019 - 2024. All rights reserved.