将形状从组中移到图层上时正确应用变换
Correctly apply transformation when moving shapes out of group onto layer
好的所以这个问题的原因是我试图一次处理多个 konva 形状。在原始项目中,通过在您想要 selected 的形状周围绘制一个瞬时矩形(矩形 selection)来 selected 形状。我已经看到其他一些 post,但它们似乎只处理 selection 本身,我有那个工作。
这是一个说明问题的代码笔示例。
link
说明:
- 单击 select 按钮将两个形状放在一个组中并应用转换器
- 旋转和缩放 selected 形状。
- 单击 deselect 按钮将形状移回图层。
有趣的部分在第 92 行之后,我正在探索将形状移回图层的不同方法。
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);
})
令人沮丧的是函数getAbsoluteTransform() 似乎给出了一个转换矩阵,但你不能直接设置一个形状的转换矩阵。但解决方案可能就像将形状矩阵设置为从 getAbsoluteTransform()
返回的矩阵一样简单
目前,Konva
核心中没有从矩阵计算属性的方法。但是你可以很容易地在网上找到它们。
extract rotation, scale values from 2d transformation matrix
根据答案,我创建了这个函数来获取属性:
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;
}
然后您可以使用该函数计算绝对变换的属性。
好的所以这个问题的原因是我试图一次处理多个 konva 形状。在原始项目中,通过在您想要 selected 的形状周围绘制一个瞬时矩形(矩形 selection)来 selected 形状。我已经看到其他一些 post,但它们似乎只处理 selection 本身,我有那个工作。
这是一个说明问题的代码笔示例。
link
说明:
- 单击 select 按钮将两个形状放在一个组中并应用转换器
- 旋转和缩放 selected 形状。
- 单击 deselect 按钮将形状移回图层。
有趣的部分在第 92 行之后,我正在探索将形状移回图层的不同方法。
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);
})
令人沮丧的是函数getAbsoluteTransform() 似乎给出了一个转换矩阵,但你不能直接设置一个形状的转换矩阵。但解决方案可能就像将形状矩阵设置为从 getAbsoluteTransform()
返回的矩阵一样简单目前,Konva
核心中没有从矩阵计算属性的方法。但是你可以很容易地在网上找到它们。
extract rotation, scale values from 2d transformation matrix
根据答案,我创建了这个函数来获取属性:
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;
}
然后您可以使用该函数计算绝对变换的属性。