aframe - 如何弯曲平面实体以匹配球面?
问题描述
我对aframe有点陌生我有一个问题:使用aframe-position-spherical-component,我设法将我的元素定位在360度,但我怎样才能“弯曲”我的元素?(以匹配球形显示)(顺便说一句,我的元素是
<html>
<head>
<script src="/lib/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-position-spherical-component/index.js"></script>
</head>
<body>
<a-scene>
<a-image src="/static/cat.jpeg" width="3" height="1.5" rotation="0 180 0" position-spherical="10 90 180"></a-image>
</a-scene>
</body>
</html>
第一次尝试解决这个问题:
现在我设法得到了接近我想要的东西,但价值是手动找到的,并不完美
<a-curvedimage src="/static/cat.jpeg" width="3" height="1.5" theta-length="64" radius="3" theta-start="-32" rotation="0 180 0" position-spherical="10 90 180"></a-curvedimage>
第二次尝试(使用非球面解决方案):
有点工作,但是图像是镜像的,并且很难实现像显示更大的图像这样的点击事件
<a-assets>
<img id="cat" src="/static/cat.jpeg" />
</a-assets>
<a-box scale="0.1 0.1 0.1" color="red"></a-box>
<a-sphere radius="10" geometry="phiLength: 20; thetaLength: 14.12; thetaStart: 65" rotation="0 210 0" material="side: back; shader: flat; src: #cat"></a-sphere>
<a-sphere radius="10" geometry="phiLength: 20; thetaLength: 14.12; thetaStart: 65" rotation="0 240 0" material="side: back; shader: flat; src: #cat"></a-sphere>
<a-sphere radius="10" geometry="phiLength: 20; thetaLength: 14.12; thetaStart: 65" rotation="0 270 0" material="side: back; shader: flat; src: #cat"></a-sphere>
<a-sphere radius="10" geometry="phiLength: 20; thetaLength: 14.12; thetaStart: 65" rotation="0 300 0" material="side: back; shader: flat; src: #cat"></a-sphere>
解决方案
<a-curvedimage>
基于圆柱体(来源),因此可能不太适合。
那么实际使用球体几何呢?
tldr 小提琴在这里
几何学
您可以使它看起来像<a-curvedimage>
使用球体的 theta 和 psi 属性:
<a-sphere geometry='thetaStart: 45; thetaLength: 45; psiLength: 45'></a-sphere>
这应该会产生一个<a-curvedimage>
ish 平面,但也会在垂直轴上弯曲。玩转 psi 和 theta 以查看更多三角形或菱形几何形状。
拟合成球体
这似乎是自定义组件的工作!如果您以前没有使用过它们,请查看链接,否则下面的组件会简单地复制球体半径和位置并将它们的值用于图像。
AFRAME.registerComponent('foo', {
schema: {
// we'll use it to provide the sphere
target: {type: selector}
},
init: function() {
let sphere = this.data.target
// make sure the sphere radius and transform is identical:
this.el.setAttribute('radius', sphere.getAttribute('radius'))
this.el.setAttribute('position', sphere.getAttribute('position'))
}
})
并像这样简单地使用它:
<!-- the background with some position and radius -->
<a-sphere id='background'></a-sphere>
<!-- the inner sphere -->
<a-sphere foo='target: #background'></a-sphere>
Z-格斗
您应该注意到图像不可见,或者它被扭曲了。到目前为止,我们有两个大小和变换相同的球体,因此渲染器将不知道哪个球体在另一个球体前面。
您可以轻松地处理这个问题 - 通过更改内球体的半径:
this.el.setAttribute('radius', sphere.getAttribute('radius') * 0.95)
或者您可以将内部球体向中心移动一点 - 就像在提供的小提琴中一样:
// grab the inner sphere's mesh
let mesh = this.el.getObject3D('mesh')
// we need an axis - I'd substract the mesh's center from the spheres center
let axis = sphere.getAttribute('position').clone()
axis.add(mesh.geometry.boundingSphere.center.clone().multiplyScalar(-1))
axis.normalize();
// move the inner sphere a bit along the axis
this.el.object3D.translateOnAxis(axis, 0.05)
点击放大图片
通常我们会使用scale
属性,但在这里我们可以操作phi
和theta
值来使图像更大。此外,您应该在放大时将图像放在前面,以防止图像之间的 z-fighting:
this.el.addEventListener('click', e => {
this.clicked = !this.clicked
// preset values depending if the image is clicked or not
let thetaLength = this.clicked ? 65 : 45
let thetaStart = this.clicked ? 35 : 45
let psiLength = this.clicked ? 65 : 45
let psiStart = this.clicked ? -10 : 0
let scale = this.clicked ? 0.95 : 1
// apply the new geometry
this.el.setAttribute('geometry', {
'thetaLength': thetaLength,
'thetaStart': thetaStart,
'phiLength': psiLength,
'phiStart' : psiStart
})
this.el.setAttribute('radius', sphere.getAttribute('radius') * scale)
})
在这里摆弄。最好将这些值保存在变量中(基值和增量),但我希望这样更容易理解。
推荐阅读
- java - 为什么我在尝试更改代码时收到错误消息?
- css - 在 CSS 中同时使用位置和显示的行为是什么?
- php - 如何在 value 属性中传递多个参数并将它们放在 name 属性中的关联数组中?
- vba - 在 VBA 中是否可以在一个中执行这两个 IF 语句?
- reactjs - 如何在反应钩子形式中使用 useEffect 显示来自寄存器的所有错误消息
- c++ - 我需要在新类中声明构造函数和析构函数吗?
- python - 目录中最多有两页pdf?
- javascript - 查找要编辑或添加的对象
- python - 'DataFrame' 对象不可调用,我该如何解决?
- flutter - 显示从 API 调用到 Flutter DropdownButton 的数据的最佳实践是什么?