/* Copyright (C) 2024 Sebastián Santisi , CSC-CONICET */ import * as THREE from 'three'; class Screen { static isMobile = 'ontouchstart' in document.documentElement; constructor(camera, renderer, center) { this.camera = camera; this.renderer = renderer; this.center = center; this.cbmove = null; this.raycaster = new THREE.Raycaster(); this.pointerScreen = new THREE.Vector2(); this.pointerWorld = new THREE.Vector3(); this.radius = 26; this.phi = -0.5; this.theta = 0.45; this.z = 15; this.aspect = 1.94; this.clicked = false; this.camera.setFocalLength(60); if(Screen.isMobile) { window.addEventListener('touchstart', (event) => { this.onClick(event); }); window.addEventListener('touchend', (event) => { this.onMouseUp(event); }); window.addEventListener('touchmove', (event) => { this.onPointerMove(event); }); } else { window.addEventListener('mouseup', (event) => { this.onMouseUp(event); }); window.addEventListener('mousedown', (event) => { this.onClick(event); }); window.addEventListener('pointermove', (event) => { this.onPointerMove(event); }); } window.addEventListener('resize', () => { this.onResize(); }); } setMoveCallBack(cbmove) { this.cbmove = cbmove; } updatePointers(event) { if(Screen.isMobile) { var touch = event.touches[0] || event.changedTouches[0]; var x = touch.pageX; var y = touch.pageY; } else { var x = event.clientX var y = event.clientY; } this.pointerScreen.x = (x / window.innerWidth) * 2 - 1; this.pointerScreen.y = -(y / window.innerHeight) * 2 + 1; this.raycaster.setFromCamera(this.pointerScreen, this.camera); var point = new THREE.Vector3(this.pointerScreen.x, this.pointerScreen.y, 0.5); point.unproject(this.camera); point.sub(this.camera.position).normalize(); var distance = -this.camera.position.z / point.z; this.pointerWorld.copy(this.camera.position).add(point.multiplyScalar(distance)); } onClick(event) { this.clicked = true; this.updatePointers(event); } onMouseUp(event) { this.clicked = false; this.updatePointers(event); ws.move(this.pointerWorld, true); if(this.cbmove) this.cbmove(this.pointerWorld, true); } onPointerMove(event) { this.updatePointers(event); if(this.clicked) { if(this.cbmove) this.cbmove(this.pointerWorld, false); } } onResize() { this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.fov = 15; this.camera.updateProjectionMatrix(); var r; if(this.camera.aspect > this.aspect) r = this.radius; else { r = this.radius * this.aspect / this.camera.aspect; } this.renderer.setSize(window.innerWidth, window.innerHeight); document.getElementById("container").style.height = window.innerHeight; document.getElementById("container").style.width = window.innerWidth; document.getElementById("rotate").style.display = this.camera.aspect > 1 ? "none" : "block"; var theta = Math.PI / 2 - this.theta; var phi = this.phi - Math.PI / 2; var x = r * Math.sin(theta) * Math.cos(phi) + this.center.x; var y = r * Math.sin(theta) * Math.sin(phi) + this.center.y; var z = r * Math.cos(theta) + this.center.z; this.camera.position.set(x, y, z); this.camera.up = new THREE.Vector3(0,0,1); this.camera.lookAt(this.center); this.raycaster.setFromCamera(this.pointerScreen, this.camera); } } export { Screen };