fix(schematic): Manuelles Zeichnen - Koordinaten und Raster korrigiert
Problem: Linien verschoben sich während des Zeichnens und waren nicht korrekt an Start-/Endpunkten ausgerichtet. Raster fehlte außerhalb der Hutschienen. Ursache: - setupMagneticSnap() verwendete getBoundingClientRect() (DOM-Pixel) statt SVG-Koordinaten über createSVGPoint().matrixTransform() - Raster wurde nur aus Hutschienen-TE berechnet, keine Randlinien Lösung: - Korrekte SVG-Koordinaten in setupMagneticSnap() via matrixTransform - Erweitertes Raster: Links/rechts Rand (alle 20px), mehr Y-Linien ober- und unterhalb der Blöcke (alle 15px statt 20px) - Snap-Radius von 20 auf 25 SVG-Einheiten erhöht Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
7de0349808
commit
5f23727202
1 changed files with 47 additions and 21 deletions
|
|
@ -8966,50 +8966,71 @@
|
||||||
gridLayer.setAttribute('class', 'schematic-wire-grid-layer');
|
gridLayer.setAttribute('class', 'schematic-wire-grid-layer');
|
||||||
gridLayer.setAttribute('pointer-events', 'none');
|
gridLayer.setAttribute('pointer-events', 'none');
|
||||||
|
|
||||||
// Collect all terminal positions and routing Y-lines
|
// Collect all terminal positions and routing lines
|
||||||
this.wireGridPoints = [];
|
this.wireGridPoints = [];
|
||||||
var pointCount = 0;
|
var pointCount = 0;
|
||||||
|
|
||||||
// Get X positions from all TE slots on all carriers
|
// SVG-Bereich ermitteln
|
||||||
|
var svgWidth = parseInt(this.svgElement.getAttribute('width')) || 800;
|
||||||
|
var svgHeight = parseInt(this.svgElement.getAttribute('height')) || 600;
|
||||||
|
|
||||||
|
// X-Positionen: TE-Slots + Rand links/rechts
|
||||||
var xPositions = [];
|
var xPositions = [];
|
||||||
|
var minX = Infinity, maxX = 0;
|
||||||
|
|
||||||
this.carriers.forEach(function(carrier) {
|
this.carriers.forEach(function(carrier) {
|
||||||
if (typeof carrier._x === 'undefined') return;
|
if (typeof carrier._x === 'undefined') return;
|
||||||
var totalTE = carrier.total_te || 12;
|
var totalTE = carrier.total_te || 12;
|
||||||
|
var carrierEndX = carrier._x + totalTE * self.TE_WIDTH;
|
||||||
|
if (carrier._x < minX) minX = carrier._x;
|
||||||
|
if (carrierEndX > maxX) maxX = carrierEndX;
|
||||||
|
|
||||||
for (var te = 1; te <= totalTE; te++) {
|
for (var te = 1; te <= totalTE; te++) {
|
||||||
// Terminal center X position for this TE
|
|
||||||
var teX = carrier._x + (te - 1) * self.TE_WIDTH + (self.TE_WIDTH / 2);
|
var teX = carrier._x + (te - 1) * self.TE_WIDTH + (self.TE_WIDTH / 2);
|
||||||
if (xPositions.indexOf(teX) === -1) xPositions.push(teX);
|
if (xPositions.indexOf(teX) === -1) xPositions.push(teX);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get Y positions from equipment terminals and routing space
|
// Rand-Raster links und rechts (alle 20px)
|
||||||
|
if (minX !== Infinity) {
|
||||||
|
for (var leftX = minX - 30; leftX > 30; leftX -= 20) {
|
||||||
|
if (xPositions.indexOf(leftX) === -1) xPositions.push(leftX);
|
||||||
|
}
|
||||||
|
for (var rightX = maxX + 30; rightX < svgWidth - 30; rightX += 20) {
|
||||||
|
if (xPositions.indexOf(rightX) === -1) xPositions.push(rightX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Y-Positionen: Terminals + Routing-Bereich
|
||||||
var yPositions = [];
|
var yPositions = [];
|
||||||
|
var minY = Infinity, maxY = 0;
|
||||||
|
|
||||||
this.equipment.forEach(function(eq) {
|
this.equipment.forEach(function(eq) {
|
||||||
if (typeof eq._y === 'undefined') return;
|
if (typeof eq._y === 'undefined') return;
|
||||||
// Top terminal Y
|
|
||||||
var topY = eq._y - 7;
|
var topY = eq._y - 7;
|
||||||
// Bottom terminal Y
|
|
||||||
var bottomY = eq._y + (eq._height || self.BLOCK_HEIGHT) + 7;
|
var bottomY = eq._y + (eq._height || self.BLOCK_HEIGHT) + 7;
|
||||||
|
if (topY < minY) minY = topY;
|
||||||
|
if (bottomY > maxY) maxY = bottomY;
|
||||||
if (yPositions.indexOf(topY) === -1) yPositions.push(topY);
|
if (yPositions.indexOf(topY) === -1) yPositions.push(topY);
|
||||||
if (yPositions.indexOf(bottomY) === -1) yPositions.push(bottomY);
|
if (yPositions.indexOf(bottomY) === -1) yPositions.push(bottomY);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add routing Y lines between carriers (for horizontal routing)
|
// Routing-Bereich ober- und unterhalb der Blöcke
|
||||||
this.carriers.forEach(function(carrier) {
|
this.carriers.forEach(function(carrier) {
|
||||||
if (typeof carrier._y === 'undefined') return;
|
if (typeof carrier._y === 'undefined') return;
|
||||||
var railCenterY = carrier._y + self.RAIL_HEIGHT / 2;
|
var railCenterY = carrier._y + self.RAIL_HEIGHT / 2;
|
||||||
var blockTop = railCenterY - self.BLOCK_HEIGHT / 2;
|
var blockTop = railCenterY - self.BLOCK_HEIGHT / 2;
|
||||||
var blockBottom = railCenterY + self.BLOCK_HEIGHT / 2;
|
var blockBottom = railCenterY + self.BLOCK_HEIGHT / 2;
|
||||||
|
|
||||||
// Add grid lines above and below the busbar area
|
// Raster oberhalb (Sammelschienen-Bereich)
|
||||||
var busbarSpace = 60; // Space for busbars
|
for (var offsetY = 20; offsetY < 150; offsetY += 15) {
|
||||||
for (var offsetY = busbarSpace + 20; offsetY < busbarSpace + 100; offsetY += self.WIRE_GRID_SIZE) {
|
|
||||||
var routeY = blockTop - offsetY;
|
var routeY = blockTop - offsetY;
|
||||||
if (routeY > 0 && yPositions.indexOf(routeY) === -1) yPositions.push(routeY);
|
if (routeY > 20 && yPositions.indexOf(routeY) === -1) yPositions.push(routeY);
|
||||||
}
|
}
|
||||||
for (var offsetY2 = busbarSpace + 20; offsetY2 < busbarSpace + 100; offsetY2 += self.WIRE_GRID_SIZE) {
|
// Raster unterhalb (Abgang-Bereich)
|
||||||
|
for (var offsetY2 = 20; offsetY2 < 150; offsetY2 += 15) {
|
||||||
var routeY2 = blockBottom + offsetY2;
|
var routeY2 = blockBottom + offsetY2;
|
||||||
if (yPositions.indexOf(routeY2) === -1) yPositions.push(routeY2);
|
if (routeY2 < svgHeight - 20 && yPositions.indexOf(routeY2) === -1) yPositions.push(routeY2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -9056,7 +9077,7 @@
|
||||||
setupMagneticSnap: function() {
|
setupMagneticSnap: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var $svg = $(this.svgElement);
|
var $svg = $(this.svgElement);
|
||||||
var magnetRadius = 20; // Distance in pixels to activate magnetic snap
|
var magnetRadius = 25; // Snap-Radius in SVG-Einheiten
|
||||||
|
|
||||||
// Remove old handler if exists
|
// Remove old handler if exists
|
||||||
$svg.off('mousemove.magneticSnap');
|
$svg.off('mousemove.magneticSnap');
|
||||||
|
|
@ -9064,21 +9085,26 @@
|
||||||
$svg.on('mousemove.magneticSnap', function(e) {
|
$svg.on('mousemove.magneticSnap', function(e) {
|
||||||
if (!self.wireDrawMode) return;
|
if (!self.wireDrawMode) return;
|
||||||
|
|
||||||
var rect = self.svgElement.getBoundingClientRect();
|
// KORREKT: SVG-Koordinaten über matrixTransform
|
||||||
var x = e.clientX - rect.left;
|
var svg = self.svgElement;
|
||||||
var y = e.clientY - rect.top;
|
var pt = svg.createSVGPoint();
|
||||||
|
pt.x = e.clientX;
|
||||||
|
pt.y = e.clientY;
|
||||||
|
var svgP = pt.matrixTransform(svg.getScreenCTM().inverse());
|
||||||
|
var x = svgP.x;
|
||||||
|
var y = svgP.y;
|
||||||
|
|
||||||
// Find nearest grid point from terminal-aligned points
|
// Find nearest grid point from terminal-aligned points
|
||||||
var nearestX = x, nearestY = y;
|
var nearestX = x, nearestY = y;
|
||||||
var minDist = Infinity;
|
var minDist = Infinity;
|
||||||
|
|
||||||
if (self.wireGridPoints && self.wireGridPoints.length > 0) {
|
if (self.wireGridPoints && self.wireGridPoints.length > 0) {
|
||||||
self.wireGridPoints.forEach(function(pt) {
|
self.wireGridPoints.forEach(function(gpt) {
|
||||||
var d = Math.sqrt(Math.pow(x - pt.x, 2) + Math.pow(y - pt.y, 2));
|
var d = Math.sqrt(Math.pow(x - gpt.x, 2) + Math.pow(y - gpt.y, 2));
|
||||||
if (d < minDist) {
|
if (d < minDist) {
|
||||||
minDist = d;
|
minDist = d;
|
||||||
nearestX = pt.x;
|
nearestX = gpt.x;
|
||||||
nearestY = pt.y;
|
nearestY = gpt.y;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue