<a-curvedimage>
основан на цилиндре ( источник ), поэтому он может не подходить.
Так как насчет использования геометрии сферы?
Tldr Fiddle здесь
Геометрия
Вы можете сделать его похожим на <a-curvedimage>
, используя свойства сферы theta и psi:
<a-sphere geometry='thetaStart: 45; thetaLength: 45; psiLength: 45'></a-sphere>
Это должно привести к плоскости <a-curvedimage>
, но также изогнутой по вертикальной оси. Поиграйте с пси и тэтой, чтобы увидеть больше треугольников или ромбовидных геометрий.
Вписывается в сферу
Это похоже на работу для пользовательского компонента ! Если вы не использовали их ранее, проверьте ссылку, в противном случае компонент ниже просто копирует радиус и положение сферы и использует их значения для изображения.
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-Fighting
Вы должны заметить, что изображение не видно или оно искажено. К настоящему времени у нас есть две сферы с одинаковым размером и преобразованиями, поэтому средство визуализации не будет знать, какая из них находится перед другой.
С этим легко справиться - изменив радиус внутренней сферы:
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-бой между изображениями:
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)
})
скрипка здесь . Было бы лучше сохранить эти значения в переменных (базовое значение и дельта), но я надеюсь, что таким образом легче понять.