feat: comprehensive SVG viewer enhancements with zoom and template preview

- Add interactive zoom functionality (25%-300% with Ctrl+scroll wheel)
- Fix SVG width constraints by injecting calculated dimensions into templates
- Implement template preview with theme-aware sample data
- Enhance UI layout with file reordering (Project → Template → CSS → Data)
- Add blue theme support for my-project alongside existing green theme
- Fix my-project field mapping from empty 'Übergeordnet' to 'Status'
- Improve SVG viewport handling with proper scrolling and container management
- Add visual zoom controls with percentage display and smart visibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-19 00:46:58 +01:00
parent 02bcf69096
commit bc756fa0cd
6 changed files with 524 additions and 33 deletions

View File

@@ -147,6 +147,82 @@
cursor: not-allowed;
opacity: 0.6;
}
/* SVG Viewer enhancements */
#viewerContainer {
position: relative;
border: 1px solid #ccd3db;
background: white;
border-radius: 8px;
min-height: 400px;
width: 100%;
overflow: hidden;
}
#viewer {
overflow: auto;
padding: 12px;
height: 100%;
max-height: 80vh;
transform-origin: top left;
transition: transform 0.2s ease;
width: 100%;
box-sizing: border-box;
min-width: 100%;
}
#viewer svg {
max-width: none !important;
height: auto !important;
width: auto !important;
display: block;
margin: 0;
min-width: 100%;
box-sizing: content-box;
}
/* Ensure zoom doesn't get clipped */
#viewer.zoomed {
overflow: visible;
width: fit-content;
height: fit-content;
max-height: none;
}
#zoomControls {
position: absolute;
top: 8px;
right: 8px;
z-index: 10;
background: rgba(255,255,255,0.95);
border-radius: 4px;
padding: 4px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
display: none;
}
#zoomControls button {
padding: 4px 8px;
margin: 2px;
border: 1px solid #ccc;
border-radius: 3px;
background: white;
cursor: pointer;
font-size: 12px;
transition: all 0.2s ease;
}
#zoomControls button:hover:not(:disabled) {
background: #f0f0f0;
border-color: #999;
transform: none; /* Override global button transform */
}
#zoomControls button:disabled {
background: #f8f8f8;
color: #ccc;
cursor: not-allowed;
}
</style>
<script src="generator.js"></script>
<script src="engine.js"></script>
@@ -155,7 +231,8 @@
<h1 id="projectName" style="color:#495057; margin-bottom:8px;">Timeline Generator</h1>
<p id="projectSubtitle" style="color:#5C6B7A; margin-top:0; margin-bottom:16px;">
Lade Projektdateien um eine Timeline zu erstellen oder verwende den lokalen Server für automatisches Laden.
Lade Projektdateien um eine Timeline zu erstellen oder verwende den lokalen Server für automatisches Laden.<br>
<small style="color:#6c757d;">💡 Zoom: Verwende die Zoom-Buttons oder Strg+Scrollrad für große Timelines.</small>
</p>
<!-- Integrated File Management -->
@@ -178,14 +255,14 @@
<div class="file-item">
<div class="file-header">
<span class="file-label">CSV Data</span>
<span class="file-label">SVG Template</span>
<label class="upload-btn">
<input type="file" id="csvInput" accept=".csv" style="display:none;" />
📊 Load
<input type="file" id="svgInput" accept=".svg" style="display:none;" />
🖼️ Load
</label>
</div>
<div class="file-status">
<span id="csvFile" class="file-name">Not loaded</span>
<span id="svgFile" class="file-name">Not loaded</span>
</div>
</div>
@@ -204,14 +281,14 @@
<div class="file-item">
<div class="file-header">
<span class="file-label">SVG Template</span>
<span class="file-label">CSV Data</span>
<label class="upload-btn">
<input type="file" id="svgInput" accept=".svg" style="display:none;" />
🖼️ Load
<input type="file" id="csvInput" accept=".csv" style="display:none;" />
📊 Load
</label>
</div>
<div class="file-status">
<span id="svgFile" class="file-name">Not loaded</span>
<span id="csvFile" class="file-name">Not loaded</span>
</div>
</div>
</div>
@@ -227,13 +304,24 @@
</div>
</div>
<div id="viewer" style="border:1px solid #ccd3db; background:white; padding:12px; border-radius:8px; overflow-x:auto; min-height:200px;">
<div style="text-align:center; padding:40px 20px; color:#6c757d;">
<div style="font-size:48px; margin-bottom:16px;">📊</div>
<h4 style="margin:0 0 8px 0; color:#495057;">Keine Timeline verfügbar</h4>
<p style="margin:0; font-size:14px;">
Lade eine <strong>Projektkonfiguration</strong> oder <strong>CSV-Datei</strong> um zu beginnen.
</p>
<!-- SVG Viewer with zoom and scroll capabilities -->
<div id="viewerContainer">
<!-- Zoom controls -->
<div id="zoomControls">
<button id="zoomIn">🔍+</button>
<button id="zoomOut">🔍-</button>
<button id="zoomReset">100%</button>
</div>
<!-- Scrollable viewer -->
<div id="viewer">
<div style="text-align:center; padding:40px 20px; color:#6c757d;">
<div style="font-size:48px; margin-bottom:16px;">📊</div>
<h4 style="margin:0 0 8px 0; color:#495057;">Keine Timeline verfügbar</h4>
<p style="margin:0; font-size:14px;">
Lade eine <strong>Projektkonfiguration</strong> oder <strong>CSV-Datei</strong> um zu beginnen.
</p>
</div>
</div>
</div>
@@ -245,6 +333,12 @@
console.log("Event handlers set up");
}
// Initialize zoom functionality
if (window.svgViewer && typeof window.svgViewer.initializeZoom === 'function') {
window.svgViewer.initializeZoom();
console.log("SVG zoom initialized");
}
// Ensure engines are loaded before auto-loading
function tryAutoLoad() {
if (window.timelineEngine && window.timelineGenerator) {