我认为您的问题有两个不同的答案:直接回答您的问题和回答您的问题:
到“如何计算每个 div 的 X 和 Y 坐标?”
注意 - 以下答案是我为线程Transform GPS-Points to Screen-Points with Perspective Projection in Android所做的帖子的重新表述。您还可以查看 Wikipedia 文章“ 3D 投影”以获得更通用的答案。
您将需要更多信息来执行透视投影,例如相机/眼睛的位置/方向、视角以及要在其上投影立方体的表面。
有了这一切,您应该能够循环您的div
元素,然后在它们的 4 个角顶点上应用您的旋转变换并投影它们中的每一个,最终使用您获得的 2D 坐标来渲染元素。
应用旋转
让我们简化一下情况。我们有:
- 一个顶点 A(x_0, y_0, z_0),你的一个角
div
- θ和δ分别定义要应用的旋转的角度。俯仰角和偏航角(Tayt-Brian 角)
...我们想要:
因此,您的线性化方程是:
x = sin(δ) * y_0 + cos(δ) * x_0
y = sin(θ) * z_0 + cos(θ) * (cos(δ) * y_0 − sin(δ) * x_0)
z = cos(θ) * z_0 i sin(θ) * (cos(δ) * y_0 − sin(δ) * x_0)
投影 - 介绍
现在我们有:
- 我们的点 D(x,y,z)
- w * h,您要投影的表面的尺寸(
innerWidth
*innerHeight
例如在您的情况下)
- 半视角 α
...我们想要:
X 屏幕坐标的架构:
E 是我们的“眼睛”在这个配置中的位置,我选择它作为原点来简化。如果不是这种情况和/或如果您还想旋转相机,则需要在后续步骤之前再次将相应的平移和/或旋转变换应用于 D。
已知焦距f可以估计:
一点几何
您可以在图片上看到三角形ECD和EBM是相似的,因此使用Side-Splitter Theorem,我们得到:
MB / CD = EM / EC
<=> X / x = f / z
(2)
使用(1)和(2),我们现在有:
X = (x / z) * ( (w / 2) / tan(α) )
注意:Y的推理相同。
实际使用
一些备注:
关于显示由 3D 立方体制成的问题div
正如我所看到的情况,上述方法存在缺陷。当然,您可以获得定义旋转和投影div
元素的 2D 坐标,但是如何使用它来渲染它们呢?.
投影后,您div
可能不再看起来是矩形的,因此很难使用简单的 CSS 进行渲染,尤其是当您的div
元素包含复杂的内容时。
因此,如果您的真正目的是显示 3D DOM 立方体,带有旋转和透视,我建议您使用CSS3 3D 变换,让浏览器进行计算。
例如,您会在此处找到仅使用 HTML 和 CSS3 实现此类多维数据集的教程。
优点是多方面的:
- 您可以从浏览器 GPU 加速中受益,使其比使用普通 JS 更流畅。
- 它会影响你的内容
div
(旋转,透视)
- 没有数学可以实现
您可能只需要担心您针对旧版本 ( http://caniuse.com/transforms3d ) 的浏览器兼容性。
如果你想动态旋转你的立方体(例如当鼠标移动时),只需使用 JS 来编辑你的 CSS 变换
例子
我很快就制作了这个JSFiddle,只需从教程中复制实现并添加一个onmousemove
处理程序来更新旋转。
希望对你有帮助,再见!