【发布时间】:2015-02-03 23:17:35
【问题描述】:
我将 3D 内容与 Three.js 与 HTML 和 SVG 内容相结合。 Three.js CSSLoader 在 3D 世界中同步 HTML 和 SVG 内容的位置方面做得非常好。
但是 SVG/HTML 坐标系是“左撇子”,而 Three.js 坐标系是“右撇子”。这基本上意味着它们的 y 轴是相反的。在 SVG/HTML 中,y/top 会随着您向下移动屏幕而上升,Three.js 使用更标准的数学约定 y 随着您向下移动屏幕而下降。
我必须不断地从一种转换到另一种,这很容易出错。我知道我不是第一个遇到这种情况的人(例如,look here)。有人想出了一个通用的解决方案吗?这是我尝试过的:
使用
.scale.y = -1在Object3D中执行所有操作。您可能会怀疑,这将是一场灾难。它将一切都从里到外,甚至不要试图把你的相机放在那里。使用
.rotate.x = Math.PI在Object3D中执行所有操作。这个比较有前途,但是z轴不再符合HTML的z-index概念。不过,这就是我现在正在使用的。在 HTML 中,不要使用
top,使用bottom。 In SVG,在<g transform="scale(1, -1)">内做所有事情<g transform="translate(0, imageHeight)">。但是,我觉得这会让开发人员更加困惑,imageHeight必须始终保持最新状态,这又是一个负担。
有没有人想出更好的办法?也许图书馆可以帮助解决这个问题?
【问题讨论】:
-
我认为解决方案是使用 THREE.js 约定为您的 SVG/HTML 创建一个世界坐标系。所以屏幕的中心(称为视口)是 0,0,0。因此 SVG/HTML 中的对象通过 viewport.center(0,0,0) + viewport.halfWidth 进行转换。
-
@beiller:我不明白这是如何解决翻转 y 轴问题的,我的问题是关于这个问题。 :-/ 我错过了什么吗?
-
也许你是,或者从你的情况来看它不可行。例如:您有一个位于世界坐标 (2,0,0) 的 CSS 精灵。要绘制精灵,您将使用以下公式:pos.x + viewportCenter.x + viewportHalfWidth.x - object.halfWidth.x。这意味着假设 (0,0,0) 视口和 10x10 精灵和 800x600 尺寸,您在距离窗口左侧 397px 处绘制 x。
-
Y 轴类似,(2,0,0) 左:397px;顶部:295 像素;对于 10x10 的精灵。
-
@beiller:选择
y = 0是作弊。 ;-) 随着 HTML 空间的 y 轴减小,3D 空间的 y 轴增加。无论如何,当然:我可以在需要指定坐标的每个地方将坐标从一个转换为另一个,但这正是我想要避免的。我想将其中一个坐标系转换为与另一个坐标系一一对应,在一个位置,以便应用程序的许多模块可以假设只有一个系统。这不是数学问题,而是 JavaScript 问题。
标签: javascript html svg three.js coordinate-systems