Stockwerksinfrastruktur zoombar gemacht

closes #30
This commit is contained in:
bigserver
2026-04-09 08:32:50 +02:00
parent 29fc683675
commit 55bbd45562
3 changed files with 132 additions and 4 deletions

View File

@@ -12,8 +12,9 @@ document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('infra-floor-canvas');
const overlay = document.getElementById('infra-floor-overlay');
const scene = document.getElementById('infra-floor-scene');
const floorSvg = canvas ? canvas.querySelector('.infra-floor-svg') : null;
if (!canvas || !overlay || !floorSvg) {
if (!canvas || !overlay || !floorSvg || !scene) {
return;
}
@@ -58,6 +59,94 @@ document.addEventListener('DOMContentLoaded', () => {
patchPanels.forEach((entry) => createMarker(entry, 'patchpanel'));
outlets.forEach((entry) => createMarker(entry, 'outlet'));
const camera = {
scale: 1,
tx: 0,
ty: 0
};
const SCALE_MIN = 0.6;
const SCALE_MAX = 3.5;
const SCALE_STEP = 0.15;
let drag = null;
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
const applyCamera = () => {
scene.style.transform = `translate(${camera.tx}px, ${camera.ty}px) scale(${camera.scale})`;
};
const zoomAtCenter = (factor) => {
const nextScale = clamp(camera.scale * factor, SCALE_MIN, SCALE_MAX);
if (Math.abs(nextScale - camera.scale) < 0.0001) {
return;
}
camera.scale = nextScale;
applyCamera();
};
const resetCamera = () => {
camera.scale = 1;
camera.tx = 0;
camera.ty = 0;
applyCamera();
};
canvas.addEventListener('wheel', (event) => {
event.preventDefault();
zoomAtCenter(event.deltaY < 0 ? (1 + SCALE_STEP) : (1 - SCALE_STEP));
}, { passive: false });
canvas.addEventListener('pointerdown', (event) => {
drag = {
x: event.clientX,
y: event.clientY,
baseX: camera.tx,
baseY: camera.ty
};
canvas.classList.add('is-dragging');
canvas.setPointerCapture(event.pointerId);
});
canvas.addEventListener('pointermove', (event) => {
if (!drag) {
return;
}
camera.tx = drag.baseX + (event.clientX - drag.x);
camera.ty = drag.baseY + (event.clientY - drag.y);
applyCamera();
});
const stopDrag = (event) => {
if (!drag) {
return;
}
drag = null;
canvas.classList.remove('is-dragging');
if (event && typeof event.pointerId === 'number') {
canvas.releasePointerCapture(event.pointerId);
}
};
canvas.addEventListener('pointerup', stopDrag);
canvas.addEventListener('pointercancel', stopDrag);
document.querySelectorAll('[data-infra-zoom]').forEach((button) => {
button.addEventListener('click', () => {
const action = button.getAttribute('data-infra-zoom');
if (action === 'in') {
zoomAtCenter(1 + SCALE_STEP);
return;
}
if (action === 'out') {
zoomAtCenter(1 - SCALE_STEP);
return;
}
resetCamera();
});
});
applyCamera();
const loadPlanDimensions = async (svgUrl) => {
if (!svgUrl) {
updateOverlayViewBox();