使用 transformMatrix 转换点在 fabricJS 中如何工作?
How does transforming points with a transformMatrix work in fabricJS?
我正在尝试在 fabric.Polygon
的角上放置点(通过 fabric.Circle
制作)。用户可以移动、缩放或旋转多边形。但是,每次修改后,我都希望有新的多边形坐标来放置我的圆圈。
在深入研究该主题时,我发现 this 对变换矩阵的很好解释。我认为这是我想要实现的完美解决方案。但是正如您在 Fiddle 中看到的那样,我的点总是偏离多边形。
因为我对几何变换等不太确定。我希望有人能找到我的错误并告诉我我遗漏了什么:)谢谢。
var canvas = new fabric.Canvas("c", {selection: false});
var polygon = new fabric.Polygon([
new fabric.Point(200, 50),
new fabric.Point(250, 150),
new fabric.Point(150, 150)
]);
polygon.on("modified", function () {
var matrix = this.calcTransformMatrix();
var transformedPoints = this.get("points").map(function(p){
return fabric.util.transformPoint(p, matrix);
});
var circles = transformedPoints.map(function(p){
return new fabric.Circle({
left: p.x,
top: p.y,
radius: 3,
fill: "red",
originX: "center",
originY: "center",
hasControls: false,
hasBorders: false,
selectable: false
});
});
this.canvas.clear().add(this).add.apply(this.canvas, circles).setActiveObject(this).renderAll();
});
canvas.add(polygon).renderAll();
canvas {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<p>
Move, scale and rotate the polygon. The three red dots should match with the corners of the polygon after each modification.
</p>
<canvas id="c" width="600" height="400"></canvas>
关于 SO 的相关问题:
- How to get polygon points in Fabric.js
- Truly rotate center of equilateral triangle in Fabric.js
- How do I transform a particular point which has been modified and update the points array of polygon?
- FabricJs and Polygon transformed coordinates
- How to multiply each point with object's transform matrix?
- How do i get point coordinates after object modified?
不是真正的几何问题。
几何部分由您解决。如果您从 fabricjs 查看内部多边形 class,您会注意到该多边形是一个 calcDimension 函数,其中每个点都有一个偏移量:
http://fabricjs.com/docs/fabric.Polygon.html
要计算 canvas 位置,您必须在转换之前添加该偏移量。
var canvas = new fabric.Canvas("c", {selection: false});
var polygon = new fabric.Polygon([
new fabric.Point(200, 50),
new fabric.Point(250, 150),
new fabric.Point(150, 150)
]);
polygon.on("modified", function () {
var matrix = this.calcTransformMatrix();
var transformedPoints = this.get("points")
.map(function(p){
return new fabric.Point(p.x - polygon.minX -polygon.width/2, p.y - polygon.minY - polygon.height/2);
})
.map(function(p){
return fabric.util.transformPoint(p, matrix);
});
var circles = transformedPoints.map(function(p){
return new fabric.Circle({
left: p.x,
top: p.y,
radius: 3,
fill: "red",
originX: "center",
originY: "center",
hasControls: false,
hasBorders: false,
selectable: false
});
});
this.canvas.clear().add(this).add.apply(this.canvas, circles).setActiveObject(this).renderAll();
});
canvas.add(polygon).renderAll();
canvas {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<p>
Move, scale and rotate the polygon. The three red dots should match with the corners of the polygon after each modification.
</p>
<canvas id="c" width="600" height="400"></canvas>
上面提供的解决方案似乎不适用于最新版本的 fabricjs。我不确定,但在调查过程中,我了解到从 2.0 版开始他们更改了多边形的坐标。相对于多边形中心的2.0点之前;在 2.0 之后,它们对 canvas;
是绝对的
我对代码片段做了一些更改,它开始使用 fabricjs v2.4.3
因此,它不仅适用于移动,而且适用于变换:例如调整大小、旋转、翻转
var canvas = new fabric.Canvas("c", {selection: false});
var polygon = new fabric.Polygon([
new fabric.Point(200, 50),
new fabric.Point(250, 150),
new fabric.Point(150, 150)
]);
polygon.on("modified", function () {
var matrix = this.calcTransformMatrix();
var transformedPoints = this.get("points")
.map(function(p){
return new fabric.Point(
p.x - polygon.pathOffset.x,
p.y - polygon.pathOffset.y);
})
.map(function(p){
return fabric.util.transformPoint(p, matrix);
});
var circles = transformedPoints.map(function(p){
return new fabric.Circle({
left: p.x,
top: p.y,
radius: 3,
fill: "red",
originX: "center",
originY: "center",
hasControls: false,
hasBorders: false,
selectable: false
});
});
this.canvas.clear().add(this).add.apply(this.canvas, circles).setActiveObject(this).renderAll();
});
canvas.add(polygon).renderAll();
canvas {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<p>
Move, scale and rotate the polygon. The three red dots should match with the corners of the polygon after each modification.
</p>
<canvas id="c" width="600" height="400"></canvas>
上面的代码可以正常工作并正确保存到数据库中,但是当我放大和移动时,偏移量仍然存在于点中。
所以,我决定在设置点的同时设置宽度和高度。
var width = self.polygon.width;
var height = polygon.height;
var scaleX = polygon.scaleX;
var scaleY = polygon.scaleY;
polygon.set({
width: width * scaleX,
height: height * scaleY,
scaleX: 1,
scaleY: 1
});
我正在尝试在 fabric.Polygon
的角上放置点(通过 fabric.Circle
制作)。用户可以移动、缩放或旋转多边形。但是,每次修改后,我都希望有新的多边形坐标来放置我的圆圈。
在深入研究该主题时,我发现 this 对变换矩阵的很好解释。我认为这是我想要实现的完美解决方案。但是正如您在 Fiddle 中看到的那样,我的点总是偏离多边形。
因为我对几何变换等不太确定。我希望有人能找到我的错误并告诉我我遗漏了什么:)谢谢。
var canvas = new fabric.Canvas("c", {selection: false});
var polygon = new fabric.Polygon([
new fabric.Point(200, 50),
new fabric.Point(250, 150),
new fabric.Point(150, 150)
]);
polygon.on("modified", function () {
var matrix = this.calcTransformMatrix();
var transformedPoints = this.get("points").map(function(p){
return fabric.util.transformPoint(p, matrix);
});
var circles = transformedPoints.map(function(p){
return new fabric.Circle({
left: p.x,
top: p.y,
radius: 3,
fill: "red",
originX: "center",
originY: "center",
hasControls: false,
hasBorders: false,
selectable: false
});
});
this.canvas.clear().add(this).add.apply(this.canvas, circles).setActiveObject(this).renderAll();
});
canvas.add(polygon).renderAll();
canvas {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<p>
Move, scale and rotate the polygon. The three red dots should match with the corners of the polygon after each modification.
</p>
<canvas id="c" width="600" height="400"></canvas>
关于 SO 的相关问题:
- How to get polygon points in Fabric.js
- Truly rotate center of equilateral triangle in Fabric.js
- How do I transform a particular point which has been modified and update the points array of polygon?
- FabricJs and Polygon transformed coordinates
- How to multiply each point with object's transform matrix?
- How do i get point coordinates after object modified?
不是真正的几何问题。 几何部分由您解决。如果您从 fabricjs 查看内部多边形 class,您会注意到该多边形是一个 calcDimension 函数,其中每个点都有一个偏移量: http://fabricjs.com/docs/fabric.Polygon.html
要计算 canvas 位置,您必须在转换之前添加该偏移量。
var canvas = new fabric.Canvas("c", {selection: false});
var polygon = new fabric.Polygon([
new fabric.Point(200, 50),
new fabric.Point(250, 150),
new fabric.Point(150, 150)
]);
polygon.on("modified", function () {
var matrix = this.calcTransformMatrix();
var transformedPoints = this.get("points")
.map(function(p){
return new fabric.Point(p.x - polygon.minX -polygon.width/2, p.y - polygon.minY - polygon.height/2);
})
.map(function(p){
return fabric.util.transformPoint(p, matrix);
});
var circles = transformedPoints.map(function(p){
return new fabric.Circle({
left: p.x,
top: p.y,
radius: 3,
fill: "red",
originX: "center",
originY: "center",
hasControls: false,
hasBorders: false,
selectable: false
});
});
this.canvas.clear().add(this).add.apply(this.canvas, circles).setActiveObject(this).renderAll();
});
canvas.add(polygon).renderAll();
canvas {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<p>
Move, scale and rotate the polygon. The three red dots should match with the corners of the polygon after each modification.
</p>
<canvas id="c" width="600" height="400"></canvas>
上面提供的解决方案似乎不适用于最新版本的 fabricjs。我不确定,但在调查过程中,我了解到从 2.0 版开始他们更改了多边形的坐标。相对于多边形中心的2.0点之前;在 2.0 之后,它们对 canvas;
是绝对的我对代码片段做了一些更改,它开始使用 fabricjs v2.4.3
因此,它不仅适用于移动,而且适用于变换:例如调整大小、旋转、翻转
var canvas = new fabric.Canvas("c", {selection: false});
var polygon = new fabric.Polygon([
new fabric.Point(200, 50),
new fabric.Point(250, 150),
new fabric.Point(150, 150)
]);
polygon.on("modified", function () {
var matrix = this.calcTransformMatrix();
var transformedPoints = this.get("points")
.map(function(p){
return new fabric.Point(
p.x - polygon.pathOffset.x,
p.y - polygon.pathOffset.y);
})
.map(function(p){
return fabric.util.transformPoint(p, matrix);
});
var circles = transformedPoints.map(function(p){
return new fabric.Circle({
left: p.x,
top: p.y,
radius: 3,
fill: "red",
originX: "center",
originY: "center",
hasControls: false,
hasBorders: false,
selectable: false
});
});
this.canvas.clear().add(this).add.apply(this.canvas, circles).setActiveObject(this).renderAll();
});
canvas.add(polygon).renderAll();
canvas {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<p>
Move, scale and rotate the polygon. The three red dots should match with the corners of the polygon after each modification.
</p>
<canvas id="c" width="600" height="400"></canvas>
上面的代码可以正常工作并正确保存到数据库中,但是当我放大和移动时,偏移量仍然存在于点中。 所以,我决定在设置点的同时设置宽度和高度。
var width = self.polygon.width;
var height = polygon.height;
var scaleX = polygon.scaleX;
var scaleY = polygon.scaleY;
polygon.set({
width: width * scaleX,
height: height * scaleY,
scaleX: 1,
scaleY: 1
});