Optimize drag and rotation with requestAnimationFrame and add proximity lines to live update
Deploy Standortplaner / deploy (push) Successful in 17s Details

This commit is contained in:
Johannes Baumeister 2026-07-06 17:52:24 +02:00
parent ce91cddb94
commit f4092ed95d
1 changed files with 72 additions and 39 deletions

111
app.js
View File

@ -524,29 +524,46 @@ document.addEventListener('DOMContentLoaded', async () => {
if (state.isEditMode) openEditPanel(turbine);
});
// Drag Update (Geometrien ziehen jetzt wieder live mit)
turbine.layers.marker.on('drag', (e) => {
const newPos = e.target.getLatLng();
turbine.latlng = newPos;
// Recalculate all geometries live during drag
const newGeoms = calculateGeometries(newPos, turbine.rd, turbine.hh, turbine.fr, turbine.ksfAngle, turbine.ksfMirrored, turbine.hersteller);
turbine.layers.sweptArea.clearLayers().addData(newGeoms.sweptArea);
turbine.layers.techDist.clearLayers().addData(newGeoms.techDist);
turbine.layers.techDistSmall.clearLayers().addData(newGeoms.techDistSmall);
turbine.layers.loadRadius.clearLayers().addData(newGeoms.loadRadius);
turbine.layers.foundation.clearLayers().addData(newGeoms.foundation);
turbine.layers.ksf.clearLayers().addData(newGeoms.ksf);
turbine.layers.blf.clearLayers().addData(newGeoms.blf);
turbine.layers.mf.clearLayers().addData(newGeoms.mf);
// Move rotation handle along with it during drag
updateRotationHandlePos(turbine);
let isDragUpdating = false;
let latestDragPos = null;
if (activeTurbine?.id === turbine.id) {
// Keep fields updated
editNr.value = turbine.nr;
updateEditPanelPosition(); // Sync floating panel
// Drag Update (Geometrien ziehen jetzt wieder live mit, aber throttled per requestAnimationFrame für Performance)
turbine.layers.marker.on('drag', (e) => {
latestDragPos = e.target.getLatLng();
if (!isDragUpdating) {
isDragUpdating = true;
requestAnimationFrame(() => {
if (!latestDragPos) {
isDragUpdating = false;
return;
}
turbine.latlng = latestDragPos;
// Recalculate all geometries live during drag
const newGeoms = calculateGeometries(latestDragPos, turbine.rd, turbine.hh, turbine.fr, turbine.ksfAngle, turbine.ksfMirrored, turbine.hersteller);
turbine.layers.sweptArea.clearLayers().addData(newGeoms.sweptArea);
turbine.layers.techDist.clearLayers().addData(newGeoms.techDist);
turbine.layers.techDistSmall.clearLayers().addData(newGeoms.techDistSmall);
turbine.layers.loadRadius.clearLayers().addData(newGeoms.loadRadius);
turbine.layers.foundation.clearLayers().addData(newGeoms.foundation);
turbine.layers.ksf.clearLayers().addData(newGeoms.ksf);
turbine.layers.blf.clearLayers().addData(newGeoms.blf);
turbine.layers.mf.clearLayers().addData(newGeoms.mf);
// Move rotation handle along with it during drag
updateRotationHandlePos(turbine);
updateProximityLines(); // Abstandslinien ebenfalls live aktualisieren
if (activeTurbine?.id === turbine.id) {
// Keep fields updated
editNr.value = turbine.nr;
updateEditPanelPosition(); // Sync floating panel
}
isDragUpdating = false;
});
}
});
@ -559,29 +576,45 @@ document.addEventListener('DOMContentLoaded', async () => {
triggerAutoSave();
});
let isRotationUpdating = false;
let latestRotationPos = null;
// Rotation Handle drag logic
turbine.layers.rotationHandle.on('drag', (e) => {
const handlePos = e.target.getLatLng();
const centerUtm = proj4(wgs84, utm32, [turbine.latlng.lng, turbine.latlng.lat]);
const handleUtm = proj4(wgs84, utm32, [handlePos.lng, handlePos.lat]);
latestRotationPos = e.target.getLatLng();
// Calculate angle
const dx = handleUtm[0] - centerUtm[0];
const dy = centerUtm[1] - handleUtm[1];
if (!isRotationUpdating) {
isRotationUpdating = true;
requestAnimationFrame(() => {
if (!latestRotationPos) {
isRotationUpdating = false;
return;
}
let angle = Math.atan2(-dx, dy) * (180 / Math.PI);
if (angle < 0) angle += 360;
const centerUtm = proj4(wgs84, utm32, [turbine.latlng.lng, turbine.latlng.lat]);
const handleUtm = proj4(wgs84, utm32, [latestRotationPos.lng, latestRotationPos.lat]);
turbine.ksfAngle = angle;
if (activeTurbine?.id === turbine.id) {
editKsfAngle.value = angle.toFixed(1);
// Calculate angle
const dx = handleUtm[0] - centerUtm[0];
const dy = centerUtm[1] - handleUtm[1];
let angle = Math.atan2(-dx, dy) * (180 / Math.PI);
if (angle < 0) angle += 360;
turbine.ksfAngle = angle;
if (activeTurbine?.id === turbine.id) {
editKsfAngle.value = angle.toFixed(1);
}
// Live Rotation Update
const newGeoms = calculateGeometries(turbine.latlng, turbine.rd, turbine.hh, turbine.fr, turbine.ksfAngle, turbine.ksfMirrored, turbine.hersteller);
turbine.layers.ksf.clearLayers().addData(newGeoms.ksf);
turbine.layers.blf.clearLayers().addData(newGeoms.blf);
turbine.layers.mf.clearLayers().addData(newGeoms.mf);
isRotationUpdating = false;
});
}
// Live Rotation Update
const newGeoms = calculateGeometries(turbine.latlng, turbine.rd, turbine.hh, turbine.fr, turbine.ksfAngle, turbine.ksfMirrored, turbine.hersteller);
turbine.layers.ksf.clearLayers().addData(newGeoms.ksf);
turbine.layers.blf.clearLayers().addData(newGeoms.blf);
turbine.layers.mf.clearLayers().addData(newGeoms.mf);
});
turbine.layers.rotationHandle.on('dragend', (e) => {