0

ok so the reason for this question is that i am trying to deal with multiple konva shapes at a time. in the original project the shapes are being selected by drawing a momentary rectangle around the shapes that you want selected (rectangular selection). I have seen some of the other post about this, but they only seem to deal with the selection itself, i have that working.

Here is a codepen example that illustrates the problem. link
Instructions:

  1. click the select button to have the two shapes put in a group and a transformer applied
  2. Rotate and scale the selected shapes.
  3. click the deselect button to have the shapes moved back onto the layer.

The parts that is interresting is after line 92, where i am exploring different methods of moving the shapes back onto the layer.

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);
    })

The frustrating part is that the function getAbsoluteTransform() seem to give a transformed matrix, but you can't set the transformation matrix of a shape directly. But the solution might be as simple as setting the shapes matrix to the one returned from getAbsoluteTransform()

elscorpio
  • 3
  • 1

1 Answers1

1

Currently, there are no methods to in Konva core to calculate attributes from the matrix. But you can easily find them online.

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

extract rotation, scale values from 2d transformation matrix

From the answers, I made this function to get attrs:

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;
}

Then you can use that function to calculate attributes from the absolute transform.

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

lavrton
  • 18,973
  • 4
  • 30
  • 63
  • Wow that certainly does the job, Thank you! – elscorpio Dec 13 '18 at 15:10
  • 1
    After closer examination and FYI for anyone who might see this. there seems to be an issue if you rotate and scale -> deselect -> select and then rotate and scale again. The shapes seems to change a little bit when deselecting. But it certainly gives a very nice starting point, saves some time – elscorpio Dec 13 '18 at 15:51
  • @elscorpio I can confirm this happens here as well. Did you come up with a fix? – Granga Aug 24 '19 at 01:19