Files
wireless-docs/diorama.js
2026-07-04 12:35:49 -04:00

56 lines
2.0 KiB
JavaScript

import {Camera} from './camera.js';
import {World} from './world.js';
export class Diorama {
constructor(elementId, requestRenderCallback) {
this.element = document.getElementById(elementId);
this.world = new World();
this.requestRender = requestRenderCallback;
this.element.style.position = "relative";
this.reset = document.createElement('button')
this.reset.textContent = 'Reset View'
this.reset.style.cssText = `
position: absolute; top: 1ch; right: 1ch;
padding: 0.5ch 1ch; background: rgba(0,0,0,0.7);
color: white; border: 1px solid gray;
cursor: pointer; display: none; z-index: 10;
`;
this.reset.addEventListener('mousedown', e => e.stopPropagation())
this.reset.addEventListener('touchstart', e => e.stopPropagation())
this.reset.addEventListener('click', () => {
this.camera.loadState();
this.reset.style.display = 'none';
});
this.element.appendChild(this.reset);
this.camera = new Camera(this.element, () => {
if (this.camera.checkpoint) this.reset.style.display = 'block';
this.requestRender();
});
this.camera.target = [0.5, 0.5, 0.5];
}
centerView() {
if (this.world.blocks.size === 0) {
this.camera.target = [0.5, 0.5, 0.5];
return;
}
let minX = Infinity, minY = Infinity, minZ = Infinity;
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
for (const block of this.world.blocks.values()) {
minX = Math.min(minX, block.x);
minY = Math.min(minY, block.y);
minZ = Math.min(minZ, block.z);
maxX = Math.max(maxX, block.x + 1);
maxY = Math.max(maxY, block.y + 1);
maxZ = Math.max(maxZ, block.z + 1);
}
this.camera.target = [(minX + maxX) / 2, (minY + maxY) / 2, (minZ + maxZ) / 2];
this.requestRender();
}
}