【问题标题】:Updating the transform matrix of one fabric object based on the changes to the transform matrix of another object根据另一个对象的变换矩阵的变化更新一个织物对象的变换矩阵
【发布时间】:2018-04-21 02:05:44
【问题描述】:

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

假设有两个多边形 - Poly1 和 Poly2。 当以任何方式修改 Poly1 时,我需要对 Poly2 应用相同的修改并需要获取 Poly2 的更新点。以下是遵循的方法:

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

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

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

  • 使用新的变换矩阵,获取更新后的点并重绘 Poly2.

但是,这种方法仅适用于移动操作。如果您在 Poly1 上调整大小或旋转,则在 Poly2 上未正确应用相同的大小。请让我知道我在这里做错了什么。

提前感谢您的帮助!

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

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);
  var oldPoly2Matrix = poly2.matrix;
  //Apply the same someMatrix to find out the new transform matrix for poly2.
  var newPoly2Matrix = fabric.util.multiplyTransformMatrices(oldPoly2Matrix, diffMatrix);

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

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

【问题讨论】:

  • 如果 poly1 被修改,你想更新 poly2 对吗?
  • 是的......

标签: html5-canvas fabricjs


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    相关资源
    最近更新 更多