如何创建一个 paper.js Path.Circle 可以 scaled/translated 与仿射矩阵,但保持圆半径始终固定?
How to create a paper.js Path.Circle that can be scaled/translated with affine matrix, but keep circle radius always fixed?
我有一个 paper.js 层,用户可以在其中绘制不同的路径(圆圈、直线等)。可以使用鼠标滚动或拖动来平移或缩放该图层。我对这一层中的 zoom/pan 路径使用仿射矩阵变换。这很好用。
我正在寻找的是创建一个可以使用矩阵平移和缩放的圆(Path.Circle 对象),只是它的半径必须始终固定(例如 5px)。所以基本上矩阵变换只需要应用到圆的位置,而不是它的轮廓。
下面是一个半径为 20px transformedPath 的圆的示例,它被放大到 2x。问题是如何在应用矩阵变换时保持圆的半径 transformedPath 固定(半径 = 20px)。
var transformedPath = new paper.Path.Circle(100,100,20);
transformedPath.strokeColor = 'black';
paper.project.activeLayer.matrix = new paper.Matrix(
2, 0,
0, 2,
0, 0
);
更新。这是一个更通用的 sketch (下面的代码),它基于 sasensi 建议的解决方案。在此示例中,蓝色圆圈的半径保持固定(这是正确的),但问题是蓝色圆圈也停留在同一个地方。
期望的结果是两个圆都移动到新位置,但蓝色圆半径保持不变。
// draw a normal circle
var normalCircle = new Path.Circle({
center: new Point(100,100),
radius: 50,
fillColor: 'orange',
});
// draw another circle that will have scale transformation reversed
var notScalingCircle = new Path.Circle({
center: new Point(100,100),
radius: 30,
fillColor: 'blue',
});
// draw instructions
new PointText({
content: 'press mouse button down to zoom in and see that blue circle size does not change',
point: view.center + [0, -80],
justification: 'center'
});
function transformLayer(matrix) {
// scale layer
// project.activeLayer.applyMatrix = false;
project.activeLayer.matrix = matrix;
// scale item with inverted amount to make it display like if it was not scaled with the layer
notScalingCircle.matrix = matrix.clone().invert();
}
var matrix = new paper.Matrix(
2,0,
0,1.5,
50,30
);
// on mouse down...
function onMouseDown() {
// ...scale up
transformLayer(matrix);
}
// on mouse up...
function onMouseUp() {
// ...scale down
transformLayer(matrix.clone().invert());
}
我认为最好的方法是,当你用给定的量缩放图层时,用倒置的量缩放你的圆圈。
这将使您的圆圈看起来像没有缩放一样。
这是一个 sketch 演示解决方案:
// draw a normal circle
var normalCircle = new Path.Circle({
center: view.center,
radius: 50,
fillColor: 'orange'
});
// draw another circle that will have scale transformation reversed
var notScalingCircle = new Path.Circle({
center: view.center,
radius: 30,
fillColor: 'blue'
});
// draw instructions
new PointText({
content: 'press mouse button down to zoom in and see that blue circle size does not change',
point: view.center + [0, -80],
justification: 'center'
});
function scaleLayer(amount) {
// scale layer
project.activeLayer.scale(amount, view.center);
// scale item with inverted amount to make it display like if it was not scaled with the layer
notScalingCircle.scale(1 / amount);
}
// on mouse down...
function onMouseDown() {
// ...scale up
scaleLayer(3);
}
// on mouse up...
function onMouseUp() {
// ...scale down
scaleLayer(1 / 3);
}
编辑
针对新示例,您只需反转项目的缩放变换,而不是所有矩阵(也包括平移和旋转)。
这是更正后的 sketch:
// draw a normal circle
var normalCircle = new Path.Circle({
center: new Point(100, 100),
radius: 50,
fillColor: 'orange'
});
// draw another circle that will have scale transformation reversed
var notScalingCircle = new Path.Circle({
center: new Point(100, 100),
radius: 30,
fillColor: 'blue'
});
// draw instructions
new PointText({
content: 'press mouse button down to zoom in and see that blue circle size does not change',
point: view.center + [0, -80],
justification: 'center'
});
function transformLayer(matrix) {
// scale layer
// project.activeLayer.applyMatrix = false;
project.activeLayer.matrix = matrix;
// just invert the scale and not all matrix
notScalingCircle.scale(1 / matrix.scaling.x, 1 / matrix.scaling.y);
}
var matrix = new paper.Matrix(
2, 0,
0, 1.5,
50, 30
);
// on mouse down...
function onMouseDown() {
// ...scale up
transformLayer(matrix);
}
// on mouse up...
function onMouseUp() {
// ...scale down
transformLayer(matrix.clone().invert());
}
我有一个 paper.js 层,用户可以在其中绘制不同的路径(圆圈、直线等)。可以使用鼠标滚动或拖动来平移或缩放该图层。我对这一层中的 zoom/pan 路径使用仿射矩阵变换。这很好用。
我正在寻找的是创建一个可以使用矩阵平移和缩放的圆(Path.Circle 对象),只是它的半径必须始终固定(例如 5px)。所以基本上矩阵变换只需要应用到圆的位置,而不是它的轮廓。
下面是一个半径为 20px transformedPath 的圆的示例,它被放大到 2x。问题是如何在应用矩阵变换时保持圆的半径 transformedPath 固定(半径 = 20px)。
var transformedPath = new paper.Path.Circle(100,100,20);
transformedPath.strokeColor = 'black';
paper.project.activeLayer.matrix = new paper.Matrix(
2, 0,
0, 2,
0, 0
);
更新。这是一个更通用的 sketch (下面的代码),它基于 sasensi 建议的解决方案。在此示例中,蓝色圆圈的半径保持固定(这是正确的),但问题是蓝色圆圈也停留在同一个地方。
期望的结果是两个圆都移动到新位置,但蓝色圆半径保持不变。
// draw a normal circle
var normalCircle = new Path.Circle({
center: new Point(100,100),
radius: 50,
fillColor: 'orange',
});
// draw another circle that will have scale transformation reversed
var notScalingCircle = new Path.Circle({
center: new Point(100,100),
radius: 30,
fillColor: 'blue',
});
// draw instructions
new PointText({
content: 'press mouse button down to zoom in and see that blue circle size does not change',
point: view.center + [0, -80],
justification: 'center'
});
function transformLayer(matrix) {
// scale layer
// project.activeLayer.applyMatrix = false;
project.activeLayer.matrix = matrix;
// scale item with inverted amount to make it display like if it was not scaled with the layer
notScalingCircle.matrix = matrix.clone().invert();
}
var matrix = new paper.Matrix(
2,0,
0,1.5,
50,30
);
// on mouse down...
function onMouseDown() {
// ...scale up
transformLayer(matrix);
}
// on mouse up...
function onMouseUp() {
// ...scale down
transformLayer(matrix.clone().invert());
}
我认为最好的方法是,当你用给定的量缩放图层时,用倒置的量缩放你的圆圈。
这将使您的圆圈看起来像没有缩放一样。
这是一个 sketch 演示解决方案:
// draw a normal circle
var normalCircle = new Path.Circle({
center: view.center,
radius: 50,
fillColor: 'orange'
});
// draw another circle that will have scale transformation reversed
var notScalingCircle = new Path.Circle({
center: view.center,
radius: 30,
fillColor: 'blue'
});
// draw instructions
new PointText({
content: 'press mouse button down to zoom in and see that blue circle size does not change',
point: view.center + [0, -80],
justification: 'center'
});
function scaleLayer(amount) {
// scale layer
project.activeLayer.scale(amount, view.center);
// scale item with inverted amount to make it display like if it was not scaled with the layer
notScalingCircle.scale(1 / amount);
}
// on mouse down...
function onMouseDown() {
// ...scale up
scaleLayer(3);
}
// on mouse up...
function onMouseUp() {
// ...scale down
scaleLayer(1 / 3);
}
编辑
针对新示例,您只需反转项目的缩放变换,而不是所有矩阵(也包括平移和旋转)。
这是更正后的 sketch:
// draw a normal circle
var normalCircle = new Path.Circle({
center: new Point(100, 100),
radius: 50,
fillColor: 'orange'
});
// draw another circle that will have scale transformation reversed
var notScalingCircle = new Path.Circle({
center: new Point(100, 100),
radius: 30,
fillColor: 'blue'
});
// draw instructions
new PointText({
content: 'press mouse button down to zoom in and see that blue circle size does not change',
point: view.center + [0, -80],
justification: 'center'
});
function transformLayer(matrix) {
// scale layer
// project.activeLayer.applyMatrix = false;
project.activeLayer.matrix = matrix;
// just invert the scale and not all matrix
notScalingCircle.scale(1 / matrix.scaling.x, 1 / matrix.scaling.y);
}
var matrix = new paper.Matrix(
2, 0,
0, 1.5,
50, 30
);
// on mouse down...
function onMouseDown() {
// ...scale up
transformLayer(matrix);
}
// on mouse up...
function onMouseUp() {
// ...scale down
transformLayer(matrix.clone().invert());
}