Я делаю виртуальный тур, используя AFrame, с <a-sky>
для изображений 360 °, некоторыми <a-circle>
для горячих точек и <a-text>
под кружками для обозначений.
Моя цель - делать тексты всегда параллельно экрану. Я уже пробовал aframe-look-at-component
на камере, но это не то, что я искал, потому что они смотрят на точку, а не на экран.
Итак, моей следующей идеей было создать невидимый курсор и скопировать его вращать тексты, но я не уверен в этом, потому что я не знаю, обновляет ли курсор свое вращение или это только основано на вращении кулачка. В любом случае, основным источником этой проблемы было то, что я не знаю, как изменить поворот моего текста после создания, я пробовал mytext.object3D.rotation
, mytext.setAttribute('rotation', newRotation)
, а также object3D.lookAt()
, но либо это не имело значения, либо это не то, что я искал.
Как лучше всего этого добиться?
Вот мой компонент точки доступа (который создает тексты на основе некоторых свойств):
AFRAME.registerPrimitive('a-hotspot', {
defaultComponents: {
hotspot: {}
},
mappings: {
for: 'hotspot.for',
to: 'hotspot.to',
legend: 'hotspot.legend',
'legend-pos': 'hotspot.legend-pos',
'legend-rot': 'hotspot.legend-rot'
}
});
AFRAME.registerComponent('hotspot', {
schema: {
for: { type: 'string' },
to: { type: 'string' },
legend: { type: 'string' },
'legend-pos': { type: 'vec3', default: {x: 0, y: -0.5, z:0}},
'legend-rot': { type: 'number', default: 0 },
positioning: { type: 'boolean', default: false }
},
init: function () {
this.shiftIsPress = false
window.addEventListener('keydown', this.handleShiftDown.bind(this))
window.addEventListener('keyup', this.handleShiftUp.bind(this))
this.tour = document.querySelector('a-tour');
if (this.data.legend)
this.addText();
this.el.addEventListener('click', this.handleClick.bind(this));
},
// Creating the text, based on hotspots props
addText: function () {
var hotspot = this.el,
position = new THREE.Vector3(hotspot.object3D.position.x, hotspot.object3D.position.y, hotspot.object3D.position.z),
text = document.createElement('a-text'),
loadedScene = document.querySelector('a-tour').getAttribute('loadedScene')
position.x += this.data['legend-pos'].x
position.y += this.data['legend-pos'].y
position.z += this.data['legend-pos'].z
console.log(this.data['legend-rot'])
// Set text attributes
text.id = `text_${this.data.for}_to_${this.data.to}`
text.setAttribute('position', position)
text.setAttribute('color', '#BE0F34')
text.setAttribute('align', 'center')
text.setAttribute('value', this.data.legend)
text.setAttribute('for', this.data.for)
if (loadedScene && loadedScene !== this.data.for) text.setAttribute('visible', false)
// Insert text after hotspot
hotspot.parentNode.insertBefore(text, hotspot.nextSibling)
},
// This part is supposed to edit the rotation
// to always fit to my idea
tick: function () {
if (this.el.getAttribute('visible')) {
var cursorRotation = document.querySelector('a-cursor').object3D.getWorldRotation()
//document.querySelector(`#text_${this.data.for}_to_${this.data.to}`).object3D.lookAt(cursorRotation)
this.updateRotation(`#text_${this.data.for}_to_${this.data.to}`)
}
},
// This parts manage the click event.
// When shift is pressed while clicking on hotspot, it enable another component
// to stick a hotspot to the camera for help me to place it on the scene
// otherwise, it change the 360° image and enbable/disable hotspots.
handleShiftDown: function (e) {
if (e.keyCode === 16) this.shiftIsPress = true
},
handleShiftUp: function (e) {
if (e.keyCode === 16) this.shiftIsPress = false
},
handleClick: function (e) {
var target = 'target: #' + this.el.id
var tour = this.tour.components['tour']
if (this.shiftIsPress)
tour.el.setAttribute('hotspot-helper', target)
else
tour.loadSceneId(this.data.to, true);
}
});
Я действительно не знаю, что делать ..
РЕДАКТИРОВАТЬ: Я нашел частичное решение: если бы у меня была геометрия для моего текста (и материала с alphaTest: 1, чтобы скрыть его), setAttribute ( 'вращение') работают, и я основываю его на вращении камеры. Проблема в том, что после этого камера заблокирована, не понимаю почему ^^
var cursorRotation = document.querySelector('a-camera').object3D.rotation
document.querySelector(`#text_${this.data.for}_to_${this.data.to}`).setAttribute('rotation', cursorRotation)
Спасибо, Navalex