我正在尝试通过CSS的方式来绕Y轴进行图像透视旋转,使得最终可见宽度等于期望的像素数。例如,我可能想要将一个
300px
的图像旋转,以便在应用旋转和透视后,图像的宽度现在是240px
(原始值的80%)。通过试错,我知道我可以设置transform: perspective(300) rotateY(-12.68)
,并将左上角点置于-240px
(这是使用图像右侧作为起点)。我还没有完全弄清楚如何反向工程化,以便为任何给定的图像宽度、透视和期望宽度计算必要的旋转角度。举个例子,对于同样的300px
图像,我现在希望旋转后它的宽度为150px
- 需要哪些计算才能得到必要的角度?这里有一个游乐场,让你了解我所寻找的内容,我已经复制了透视和旋转变换所做的数学计算,以计算左侧点的最终位置,但我还没有能够弄清楚如何解决由矩阵数学和多个步骤组成的角度问题。:https://repl.it/@BenSlinger/PerspectiveWidthDemo
const calculateLeftTopPointAfterTransforms = (perspective, rotation, width) => {
// convert degrees to radians
const rRad = rotation * (Math.PI / 180);
// place the camera
const cameraMatrix = math.matrix([0, 0, -perspective]);
// get the upper left point of the image based on middle right transform origin
const leftMostPoint = math.matrix([-width, -width / 2, 0]);
const rotateYMatrix = math.matrix([
[Math.cos(-rRad), 0, -Math.sin(-rRad)],
[0, 1, 0],
[Math.sin(-rRad), 0, Math.cos(-rRad)],
]);
// apply rotation to point
const rotatedPoint = math.multiply(rotateYMatrix, leftMostPoint);
const cameraProjection = math.subtract(rotatedPoint, cameraMatrix);
const pointInHomogenizedCoords = math.multiply(math.matrix([
[1, 0, 0 / perspective, 0],
[0, 1, 0 / perspective, 0],
[0, 0, 1, 0],
[0, 0, 1 / perspective, 0],
]), cameraProjection.resize([4], 1));
const finalPoint = [
math.subset(pointInHomogenizedCoords, math.index(0))
/ math.subset(pointInHomogenizedCoords, math.index(3)),
math.subset(pointInHomogenizedCoords, math.index(1))
/ math.subset(pointInHomogenizedCoords, math.index(3)),
];
return finalPoint;
}
<div id="app"></div>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.js"></script>
<script type="text/babel" data-plugins="transform-class-properties" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/6.0.4/math.min.js"></script>
非常感谢任何帮助!