AFRAME.registerComponent('tap-to-place', { init() { this.raycaster = new THREE.Raycaster() this.camera = document.getElementById('camera') this.threeCamera = this.camera.getObject3D('camera') this.ground = document.getElementById('ground') document.querySelector('#tap-to-place-cursor').setAttribute('visible', 'true') // 2D coordinates of the raycast origin, in normalized device coordinates (NDC)---X and Y // components should be between -1 and 1. Here we want the cursor in the center of the screen. this.rayOrigin = new THREE.Vector2(0, 0) this.cursorLocation = new THREE.Vector3(0, 0, 0) this.onTap = this.onTap.bind(this) this.el.sceneEl.addEventListener('touchstart', this.onTap) }, remove() { this.el.sceneEl.removeEventListener('touchstart', this.onTap) }, tick() { this.raycaster.setFromCamera(this.rayOrigin, this.threeCamera) const intersects = this.raycaster.intersectObject(this.ground.object3D, true) if (intersects.length > 0) { const [intersect] = intersects this.cursorLocation = intersect.point } this.el.object3D.position.y = 0.1 this.el.object3D.position.lerp(this.cursorLocation, 0.4) this.el.object3D.lookAt(this.threeCamera.position.x, this.el.object3D.position.y, this.threeCamera.position.z) }, onTap() { document.querySelector('#tap-to-place-cursor').setAttribute('visible', 'false') this.el.emit('placed') this.el.removeAttribute('tap-to-place') }, })