基于对另一个对象的变换矩阵的更改来更新一个结构对象的变换矩阵

时间:2017-11-08 11:42:01

标签: html5-canvas fabricjs

我正在尝试同步两个结构对象的移动,调整大小和旋转操作。

考虑有两个多边形--Poly1和Poly2。 当以任何方式修改Poly1时,我需要在Poly2上应用相同的修改,并且需要获取Poly2的更新点。以下是采用的方法:

  • 在修改之前和之后获取Poly1的变换矩阵。

  • 使用它们来获取修改变换矩阵的矩阵 它原来是修改后的状态。

  • 将上一步的矩阵乘以当前变换 Poly2矩阵得到新的变换矩阵。

  • 使用新的变换矩阵并获取更新的点并重绘 POLY2。

但是,这种方法仅适用于移动操作。如果在Poly1上调整大小或旋转,则在Poly2上无法正确应用。请告诉我这里我做错了什么。

提前感谢您的帮助!!

示例代码 - 蓝色是Poly1,红色是Poly2



canvas {
  border: 1px solid;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.js"></script>
<canvas id="c" height="500" width="600"></canvas>

<button id="update" onclick="updatePoly2()">
  Update red shape
</button>
&#13;
{{1}}
&#13;
&#13;
&#13;

jsfiddle - https://jsfiddle.net/btxp0ck6/

1 个答案:

答案 0 :(得分:0)

将translateX和translateY计算从矩阵mulplication更改为简单减法后,工作正常。请在此处提供代码以供参考。

&#13;
&#13;
var oldPoly1Matrix;
var canvas = new fabric.Canvas('c');
var srcOptions = {
  stroke: 'blue',
  fill: '',
  type: 'src'
};
var destOptions = {
  stroke: 'red',
  fill: '',
  selectable: false,
  hasControls: false,
  hasBorders: false,
  type: 'dest'
};
var poly1 = new fabric.Polygon([{
  x: 60,
  y: 40
}, {
  x: 160,
  y: 40
}, {
  x: 160,
  y: 140
}, {
  x: 60,
  y: 140
}], srcOptions);
var poly2 = new fabric.Polygon([{
  x: 60,
  y: 300
}, {
  x: 160,
  y: 300
}, {
  x: 160,
  y: 400
}, {
  x: 60,
  y: 400
}], destOptions);


canvas.add(poly1).add(poly2);
oldPoly1Matrix = poly1.calcTransformMatrix();
var originalPoly2Matrix = poly2.calcTransformMatrix();
poly2.matrix = originalPoly2Matrix;

function updatePoly2() {
  var newPoly1Matrix = poly1.calcTransformMatrix();
  var oldPoly1MatrixInverted = fabric.util.invertTransform(oldPoly1Matrix);
  //newMatrix = oldMatrix * someMatrix
  //therefore,someMatrix = newMatrix / oldMatrix = newMatrix * inverse(oldMatrix);
  var diffMatrix = fabric.util.multiplyTransformMatrices(newPoly1Matrix, oldPoly1MatrixInverted,true);
  diffMatrix[4] = newPoly1Matrix[4] - oldPoly1Matrix[4];
  diffMatrix[5] = newPoly1Matrix[5] - oldPoly1Matrix[5];
  var oldPoly2Matrix = poly2.calcTransformMatrix();
  //Apply the same someMatrix to find out the new transform matrix for poly2.
  var newPoly2Matrix = fabric.util.multiplyTransformMatrices(oldPoly2Matrix, diffMatrix,true);
  newPoly2Matrix[4] = oldPoly2Matrix[4] + diffMatrix[4];
  newPoly2Matrix[5] = oldPoly2Matrix[5] + diffMatrix[5];
  var updatedPoints = poly2.get('points')
    .map(function(p) {
      return new fabric.Point(p.x - poly2.minX - poly2.width / 2, p.y - poly2.minY - poly2.height / 2);
    })
    .map(function(p) {
      return fabric.util.transformPoint(p, newPoly2Matrix);
    });

  oldPoly1Matrix = newPoly1Matrix;
  poly2.remove();
  poly2 = new fabric.Polygon(updatedPoints, destOptions);
  poly2.matrix = newPoly2Matrix;
  canvas.add(poly2);
}
&#13;
canvas {
  border: 1px solid;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.js"></script>
<canvas id="c" height="500" width="600"></canvas>

<button id="update" onclick="updatePoly2()">
  Update red shape
</button>
&#13;
&#13;
&#13;

Jsfiddle - https://jsfiddle.net/btxp0ck6/1/