css aufgeräumt

This commit is contained in:
2026-02-12 08:35:53 +01:00
parent fb4ee93b17
commit b469a7ab33
5 changed files with 507 additions and 265 deletions

View File

@@ -1,6 +1,12 @@
(() => {
const SVG_NS = 'http://www.w3.org/2000/svg';
const MIN_DRAW_SIZE = 4;
const MIN_CANVAS_WIDTH = 200;
const MIN_CANVAS_HEIGHT = 120;
const FORM_FACTOR_PRESETS = {
'19': { width: 760, height: 80 },
'10': { width: 420, height: 80 }
};
function initEditor() {
const editor = document.getElementById('device-type-shape-editor');
@@ -31,6 +37,13 @@
deleteButton: document.getElementById('shape-delete')
};
const metaInputs = {
formFactor: document.getElementById('shape-meta-form-factor'),
rackHeight: document.getElementById('shape-meta-rack-height'),
canvasWidth: document.getElementById('shape-meta-canvas-width'),
canvasHeight: document.getElementById('shape-meta-canvas-height')
};
const fieldVisibility = {
width: editor.querySelector('[data-field="width"]'),
height: editor.querySelector('[data-field="height"]'),
@@ -53,11 +66,20 @@
offsetY: 0
};
let selectedShapeId = null;
let shapes = normalizeShapeList(readJson(hiddenInput.value));
let shapes = [];
let meta = getDefaultMeta();
const definition = readDefinition(hiddenInput.value);
shapes = normalizeShapeList(definition.shapes);
meta = definition.meta;
bindToolbarEvents(editor);
bindCanvasPointerEvents(svg);
bindOverlayEvents(overlay);
bindMetaEvents();
applyFormFactorPreset();
applyMetaToInputs();
persist();
render();
function bindToolbarEvents(root) {
@@ -218,6 +240,63 @@
});
}
function bindMetaEvents() {
Object.values(metaInputs).forEach((input) => {
if (!input) {
return;
}
const eventName = input.tagName === 'SELECT' ? 'change' : 'input';
input.addEventListener(eventName, handleMetaInputChange);
});
}
function handleMetaInputChange(event) {
const targetId = event?.target?.id;
applyMetaFromInputs();
applyFormFactorPreset(targetId);
applyMetaToInputs();
persist();
render();
}
function applyMetaFromInputs() {
if (!metaInputs.formFactor) {
return;
}
meta.formFactor = normalizeFormFactor(metaInputs.formFactor.value);
meta.heightHe = Math.max(1, toNumberOrDefault(metaInputs.rackHeight.value, meta.heightHe));
meta.canvasWidth = Math.max(MIN_CANVAS_WIDTH, toNumberOrDefault(metaInputs.canvasWidth.value, meta.canvasWidth));
meta.canvasHeight = Math.max(MIN_CANVAS_HEIGHT, toNumberOrDefault(metaInputs.canvasHeight.value, meta.canvasHeight));
}
function applyMetaToInputs() {
if (!metaInputs.formFactor) {
return;
}
metaInputs.formFactor.value = meta.formFactor;
metaInputs.rackHeight.value = meta.heightHe;
metaInputs.canvasWidth.value = meta.canvasWidth;
metaInputs.canvasHeight.value = meta.canvasHeight;
}
function applyFormFactorPreset(triggerId) {
if (!['shape-meta-form-factor', 'shape-meta-rack-height'].includes(triggerId) && triggerId !== undefined) {
return;
}
if (meta.heightHe !== 1) {
return;
}
const preset = FORM_FACTOR_PRESETS[meta.formFactor];
if (!preset) {
return;
}
meta.canvasWidth = Math.max(MIN_CANVAS_WIDTH, preset.width);
meta.canvasHeight = Math.max(MIN_CANVAS_HEIGHT, preset.height);
}
function applyOverlayToSelectedShape() {
const shape = findShape(selectedShapeId);
if (!shape) {
@@ -248,6 +327,7 @@
function render() {
renderToolState();
updateCanvasDimensions();
renderCanvas();
renderOverlay();
}
@@ -261,7 +341,8 @@
}
function renderCanvas() {
svg.querySelectorAll('.shape-object').forEach((el) => el.remove());
svg.querySelectorAll('.shape-object, .shape-auto-frame').forEach((el) => el.remove());
renderAutoFrame();
shapes.forEach((shape) => {
const element = createSvgShapeElement(shape);
@@ -280,6 +361,39 @@
});
}
function renderAutoFrame() {
if (!['19', '10'].includes(meta.formFactor)) {
return;
}
const padding = 4;
const frameWidth = Math.max(0, meta.canvasWidth - padding * 2);
const frameHeight = Math.max(0, meta.canvasHeight - padding * 2);
if (frameWidth <= 0 || frameHeight <= 0) {
return;
}
const frame = document.createElementNS(SVG_NS, 'rect');
frame.setAttribute('x', String(padding));
frame.setAttribute('y', String(padding));
frame.setAttribute('width', String(frameWidth));
frame.setAttribute('height', String(frameHeight));
frame.setAttribute('fill', '#ffffff');
frame.setAttribute('stroke', '#000000');
frame.setAttribute('stroke-width', '1');
frame.setAttribute('class', 'shape-auto-frame');
frame.setAttribute('pointer-events', 'none');
svg.appendChild(frame);
}
function updateCanvasDimensions() {
const width = Math.max(MIN_CANVAS_WIDTH, meta.canvasWidth);
const height = Math.max(MIN_CANVAS_HEIGHT, meta.canvasHeight);
svg.setAttribute('viewBox', `0 0 ${width} ${height}`);
svg.style.height = `${height}px`;
svg.style.minHeight = `${height}px`;
}
function renderOverlay() {
const selected = findShape(selectedShapeId);
const hasSelection = !!selected;
@@ -319,7 +433,16 @@
}
function persist() {
hiddenInput.value = JSON.stringify(shapes);
const payload = {
shapes,
meta: {
formFactor: meta.formFactor,
heightHe: meta.heightHe,
canvasWidth: meta.canvasWidth,
canvasHeight: meta.canvasHeight
}
};
hiddenInput.value = JSON.stringify(payload);
}
function findShape(id) {
@@ -542,6 +665,56 @@
}
}
function readDefinition(raw) {
const parsed = readJson(raw);
if (Array.isArray(parsed)) {
return {
shapes: parsed,
meta: getDefaultMeta()
};
}
if (parsed && typeof parsed === 'object') {
return {
shapes: Array.isArray(parsed.shapes) ? parsed.shapes : [],
meta: normalizeMeta(parsed.meta ?? parsed)
};
}
return {
shapes: [],
meta: getDefaultMeta()
};
}
function normalizeMeta(source) {
const base = getDefaultMeta();
if (!source || typeof source !== 'object') {
return base;
}
return {
formFactor: normalizeFormFactor(source.formFactor ?? source.rackFormFactor ?? base.formFactor),
heightHe: Math.max(1, toNumberOrDefault(source.heightHe ?? source.rackHeight ?? base.heightHe, base.heightHe)),
canvasWidth: Math.max(MIN_CANVAS_WIDTH, toNumberOrDefault(source.canvasWidth ?? source.width ?? base.canvasWidth, base.canvasWidth)),
canvasHeight: Math.max(MIN_CANVAS_HEIGHT, toNumberOrDefault(source.canvasHeight ?? source.height ?? base.canvasHeight, base.canvasHeight))
};
}
function getDefaultMeta() {
return {
formFactor: 'other',
heightHe: 1,
canvasWidth: 800,
canvasHeight: 360
};
}
function normalizeFormFactor(value) {
const normalized = String(value || '').trim();
return ['10', '19'].includes(normalized) ? normalized : 'other';
}
function normalizeColor(value, fallback) {
const v = String(value || '').trim();
if (/^#[0-9a-fA-F]{6}$/.test(v)) {