【问题标题】:Problems with selecting objects from a group从组中选择对象的问题
【发布时间】:2020-09-22 23:22:56
【问题描述】:

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

  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】:

    fabricJS 中的选择区域码没有考虑分组转换,即使fabricJS 目前没有理由支持分组选择,也许可以解决这个问题。 请注意,您可以在不编写自定义代码来查找内部对象的情况下完成您所取得的成就:

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

    fabricJS 支持在组内找到开箱即用的目标,将 subTargetCheck 布尔属性启用为 true

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 2020-07-27
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 2018-06-11
      • 2020-02-23
      • 2020-05-20
      相关资源
      最近更新 更多