首页 > 解决方案 > 将形状从组中移出到图层上时正确应用变换

问题描述

好的,所以这个问题的原因是我试图一次处理多个 konva 形状。在原始项目中,通过在要选择的形状周围绘制一个瞬时矩形来选择形状(矩形选择)。我看过其他一些关于这个的帖子,但他们似乎只处理选择本身,我有这个工作。

这是一个说明问题的 codepen 示例。 链接
说明:

  1. 单击选择按钮将两个形状放在一个组中并应用一个变压器
  2. 旋转和缩放选定的形状。
  3. 单击取消选择按钮将形状移回图层上。

有趣的部分在第 92 行之后,我正在探索将形状移回图层的不同方法。

children.toArray().forEach(e => {
      // Need to apply transformations correctly before putting back on layer

      //Method 1
      if (method === 1) {
        let newTransforms = e.getAbsoluteTransform();
        let localTransforms = e.getTransform();
        let m = newTransforms.getMatrix();
        let matrices = getMatrix(e);

        console.log("matrix before : ");
        console.log(matrices); 

        e.rotation(selectionGroupRotation);
        e.skew({ x: m[1], y: m[2] });
        e.scale({ x: m[0], y: m[3] });
        e.position({ x: m[4], y: m[5] })

        m = newTransforms.getMatrix();
        matrices = getMatrix(e);

        console.log("matrix after : ");
        // console.log(m); 
        console.log(matrices);
      }

      //Method 2
       if (method === 2) {
        let groupPos = selectionGroup.position();
        let point = { x: groupPos.x, y: groupPos.y };
        let groupScale = selectionGroup.scale();
        let groupRotation = selectionGroup.rotation();
        let configGroupMatrix = selectionGroup.getTransform(); 
        let newpos = configGroupMatrix.point(point);

        e.rotation(selectionGroupRotation + e.rotation());
        e.scaleX(groupScale.x * e.scaleX());
        e.scaleY(groupScale.y * e.scaleY());
        let finalpos = {
          x: groupPos.x + e.x(),
          y: groupPos.y + e.y()
                       }
        e.x(finalpos.x);
        e.y(finalpos.y);

      }

      e.moveTo(layer);
    })

令人沮丧的部分是函数 getAbsoluteTransform() 似乎给出了一个变换矩阵,但你不能直接设置一个形状的变换矩阵。但解决方案可能就像将形状矩阵设置为从 getAbsoluteTransform() 返回的矩阵一样简单

标签: konvajs

解决方案


目前,Konva核心中没有从矩阵计算属性的方法。但是你可以很容易地在网上找到它们。

https://math.stackexchange.com/questions/13150/extracting-rotation-scale-values-from-2d-transformation-matrix

从二维变换矩阵中提取旋转、缩放值

从答案中,我制作了这个函数来获取属性:

function decompose(mat) {
  var a = mat[0];
  var b = mat[1];
  var c = mat[2];
  var d = mat[3];
  var e = mat[4];
  var f = mat[5];

  var delta = a * d - b * c;

  let result = {
    x: e,
    y: f,
    rotation: 0,
    scaleX: 0,
    scaleY: 0,
    skewX: 0,
    skewY: 0,
  };

  // Apply the QR-like decomposition.
  if (a != 0 || b != 0) {
    var r = Math.sqrt(a * a + b * b);
    result.rotation = b > 0 ? Math.acos(a / r) : -Math.acos(a / r);
    result.scaleX = r;
    result.scaleY = delta / r;
    result.skewX = Math.atan((a * c + b * d) / (r * r));
    result.scleY = 0;
  } else if (c != 0 || d != 0) {
    var s = Math.sqrt(c * c + d * d);
    result.rotation =
      Math.PI / 2 - (d > 0 ? Math.acos(-c / s) : -Math.acos(c / s));
    result.scaleX = delta / s
    result.scaleY = s;
    result.skewX = 0
    result.skewY = Math.atan((a * c + b * d) / (s * s));
  } else {
    // a = b = c = d = 0
  }

  result.rotation *= 180 / Math.PI;
  return result;
}

然后,您可以使用该函数从绝对变换中计算属性。

演示:https ://codepen.io/lavrton/pen/dwGPBz?editors=1010


推荐阅读