【发布时间】:2021-01-17 22:20:19
【问题描述】:
我有一个简单的变换类,可以以任意顺序在 div 上应用平移、缩放和旋转:
class TransformDiv{
constructor(div)
{
this.div = div;
this.translateX = 0;
this.translateY = 0;
this.scaleX = 1;
this.scaleY = 1;
this.shearX = 0;
this.shearY = 0;
}
translate(x, y)
{
this.translateX += x;
this.translateY += y;
this.setTransform();
}
scale(x, y, anchorX = 0, anchorY = 0)
{
this.scaleX *= x;
this.shearX *= x;
this.scaleY *= y;
this.shearY *= y;
this.translateX -= (this.translateX - anchorX) * (1 - x);
this.translateY -= (this.translateY - anchorY) * (1 - y);
this.setTransform();
}
rotate(rad, anchorX = 0, anchorY = 0)
{
let cos = Math.cos(rad);
let sin = Math.sin(rad);
// the composition of two successive rotations are additive
let newScaleX = this.scaleX * cos + this.shearX * sin;
let newShearX = this.scaleX * (-sin) + this.shearX * cos;
let newShearY = this.shearY * cos + this.scaleY * sin;
let newScaleY = this.shearY * (-sin) + this.scaleY * cos;
this.scaleX = newScaleX;
this.shearX = newShearX;
this.shearY = newShearY;
this.scaleY = newScaleY;
//rotation about an arbitrary point
let originX = (this.translateX - anchorX);
let originY = (this.translateY - anchorY);
this.translateX -= (originY * sin - originX * (cos - 1));
this.translateY -= (-originY * (cos - 1) - originX * sin);
this.setTransform();
}
setTransform()
{
this.div.style.transform = `matrix(${this.scaleX}, ${this.shearY}, ${this.shearX}, ${this.scaleY}, ${this.translateX}, ${this.translateY})`;
}
}
当我想在一个不统一的比例后旋转时出现问题。
编辑 - 较新的交互式示例:https://codepen.io/manstie/pen/RwGGOmB
这是我做的例子: https://jsfiddle.net/ft61q230/1/
在这里的例子中:
div2.translate(100, 100);
div2.scale(2, 1, 100, 100);
div2.rotate(Math.PI / 2, 100, 100);
预期的结果是Test 1 Text 和Test 2 Text 的长度相同,就好像你从div 的左上角顺时针旋转了90 度;但正如您所见,结果是我正在执行的旋转逻辑保留了世界空间轴上的比例,所以现在Test 2 Text 的高度是原来的两倍而不是两倍。
目前的结果:
期望的结果:
当前的旋转逻辑是基于将构成旋转的现有变换矩阵乘以另一个包含旋转角度的变换矩阵,但我意识到它并不那么简单,我缺少一些东西来保留局部轴规模。
感谢您的帮助。
编辑:
被推荐 DOMMatrix 为我完成所有这些数学运算,但它有同样的问题,虽然有一些我认为不准确的偏差:
https://jsfiddle.net/heqo7vrt/1/
倾斜是由缩放函数在旋转时缩放其局部 X 轴 引起的,然后在不保持局部 X 轴缩放后旋转。此外,DOMMatrix translate 函数在其本地轴上应用了翻译,这在我的情况下是不需要的,但如果它的旋转功能按预期工作,我将能够使用它。
【问题讨论】:
标签: javascript graphics 2d transform css-transforms