periodic_table / InteractionController.js
AK51's picture
Upload 18 files
ab59545 verified
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
export class InteractionController {
constructor(sceneManager, periodicTable, spectrumDisplay) {
this.sceneManager = sceneManager;
this.periodicTable = periodicTable;
this.spectrumDisplay = spectrumDisplay;
this.controls = null;
this.renderer = sceneManager.getRenderer();
this.camera = sceneManager.getCamera();
}
initialize() {
// Set up OrbitControls
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.controls.enableDamping = true;
this.controls.dampingFactor = 0.05;
this.controls.minDistance = 10;
this.controls.maxDistance = 50;
this.controls.enablePan = true;
// Mouse move for hover
this.renderer.domElement.addEventListener('mousemove', (e) => this.onMouseMove(e));
// Click for selection
this.renderer.domElement.addEventListener('click', (e) => this.onClick(e));
// ESC key for deselection
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
this.deselectElement();
}
});
// Update controls in animation loop
this.updateControls();
}
onMouseMove(event) {
const rect = this.renderer.domElement.getBoundingClientRect();
const x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
const y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
const element = this.periodicTable.getElementAtPosition(x, y, this.camera);
if (element) {
this.renderer.domElement.style.cursor = 'pointer';
this.periodicTable.highlightElement(element);
} else {
this.renderer.domElement.style.cursor = 'default';
this.periodicTable.highlightElement(null);
}
}
onClick(event) {
const rect = this.renderer.domElement.getBoundingClientRect();
const x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
const y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
const element = this.periodicTable.getElementAtPosition(x, y, this.camera);
if (element) {
this.periodicTable.selectElement(element);
this.spectrumDisplay.showSpectrum(element);
} else {
this.deselectElement();
}
}
deselectElement() {
this.periodicTable.selectElement(null);
this.spectrumDisplay.hideSpectrum();
}
updateControls() {
const animate = () => {
requestAnimationFrame(animate);
if (this.controls) {
this.controls.update();
}
};
animate();
}
dispose() {
if (this.controls) {
this.controls.dispose();
}
}
}