56 lines
2.0 KiB
JavaScript
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();
|
|
}
|
|
} |