Files
aza/APP/logo-tool/index.html
2026-03-30 07:59:11 +02:00

435 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Logo AI Pixel-Perfect Optimizer</title>
<!-- Keine externe Tracing-Library mehr nötig KI analysiert das Bild direkt -->
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Segoe UI', system-ui, sans-serif;
background: #111;
color: #e0e0e0;
min-height: 100vh;
}
/* ─── Header ──────────────────────── */
.header {
background: linear-gradient(135deg, #1a1a2e, #16213e);
padding: 20px 30px;
border-bottom: 1px solid #333;
display: flex;
align-items: center;
justify-content: space-between;
}
.header h1 { font-size: 1.4em; font-weight: 600; }
.header h1 span { color: #4a9eff; }
/* ─── Layout ──────────────────────── */
.app-layout {
display: grid;
grid-template-columns: 320px 1fr;
height: calc(100vh - 70px);
}
/* ─── Linke Sidebar ───────────────── */
.sidebar {
background: #1a1a1a;
border-right: 1px solid #333;
overflow-y: auto;
padding: 16px;
display: flex;
flex-direction: column;
gap: 14px;
}
.panel {
background: #222;
border: 1px solid #333;
border-radius: 8px;
padding: 14px;
}
.panel-title {
font-size: 0.8em;
text-transform: uppercase;
letter-spacing: 1px;
color: #888;
margin-bottom: 12px;
font-weight: 600;
}
/* Upload */
.upload-zone {
border: 2px dashed #444;
border-radius: 8px;
padding: 20px;
text-align: center;
cursor: pointer;
transition: border-color 0.2s, background 0.2s;
}
.upload-zone:hover, .upload-zone.drag-over {
border-color: #4a9eff;
background: rgba(74, 158, 255, 0.05);
}
.upload-zone p { font-size: 0.9em; color: #999; margin-top: 6px; }
.upload-zone .icon { font-size: 2em; margin-bottom: 4px; }
#logo-input { display: none; }
/* Slider Controls */
.control-row {
display: flex;
flex-direction: column;
gap: 4px;
margin-bottom: 10px;
}
.control-row:last-child { margin-bottom: 0; }
.control-label {
display: flex;
justify-content: space-between;
font-size: 0.85em;
}
.control-label .value { color: #4a9eff; font-weight: 600; font-variant-numeric: tabular-nums; }
input[type="range"] {
width: 100%;
-webkit-appearance: none;
background: #333;
height: 4px;
border-radius: 2px;
outline: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 16px; height: 16px;
background: #4a9eff;
border-radius: 50%;
cursor: pointer;
box-shadow: 0 0 6px rgba(74,158,255,0.4);
}
/* ─── KI-Steuerung ────────────────── */
.ai-section {
background: linear-gradient(135deg, #1a1a2e, #1e2a3a);
border: 1px solid #2a3a5c;
}
.api-row {
display: flex;
gap: 8px;
margin-bottom: 10px;
}
.api-row select, .api-row input {
background: #111;
border: 1px solid #444;
color: #ddd;
border-radius: 4px;
padding: 6px 8px;
font-size: 0.85em;
}
.api-row select { width: 110px; }
.api-row input { flex: 1; }
.ai-input-area {
position: relative;
}
.ai-input-area textarea {
width: 100%;
min-height: 80px;
background: #111;
border: 1px solid #444;
color: #ddd;
border-radius: 6px;
padding: 10px;
font-size: 0.9em;
font-family: inherit;
resize: vertical;
}
.ai-input-area textarea:focus {
border-color: #4a9eff;
outline: none;
}
.ai-input-area textarea::placeholder { color: #666; }
.btn-ai {
width: 100%;
margin-top: 8px;
background: linear-gradient(135deg, #2563eb, #1d4ed8);
color: white;
border: none;
padding: 10px;
border-radius: 6px;
font-size: 0.9em;
font-weight: 600;
cursor: pointer;
transition: opacity 0.2s;
}
.btn-ai:hover { opacity: 0.9; }
.btn-ai:disabled { opacity: 0.4; cursor: not-allowed; }
.ai-log {
margin-top: 8px;
max-height: 120px;
overflow-y: auto;
font-size: 0.75em;
font-family: 'Consolas', monospace;
color: #6a8;
background: #0a0a0a;
border-radius: 4px;
padding: 6px 8px;
display: none;
}
.ai-log.visible { display: block; }
.ai-log .error { color: #e55; }
.ai-log .info { color: #6a8; }
/* ─── Hauptbereich ────────────────── */
.main-area {
display: flex;
flex-direction: column;
background: #161616;
}
/* Toolbar */
.toolbar {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
background: #1a1a1a;
border-bottom: 1px solid #333;
}
.toolbar .btn {
background: #333;
color: #ddd;
border: 1px solid #444;
border-radius: 4px;
padding: 6px 14px;
font-size: 0.85em;
cursor: pointer;
}
.toolbar .btn:hover { background: #444; }
.toolbar .btn.primary {
background: #28a745;
border-color: #28a745;
color: white;
}
.toolbar .btn.primary:hover { background: #22943e; }
.toolbar .spacer { flex: 1; }
.toolbar .zoom-info {
font-size: 0.8em;
color: #888;
font-variant-numeric: tabular-nums;
}
.view-toggle {
display: flex;
border: 1px solid #444;
border-radius: 4px;
overflow: hidden;
}
.view-toggle button {
background: #2a2a2a;
color: #aaa;
border: none;
padding: 5px 12px;
font-size: 0.8em;
cursor: pointer;
}
.view-toggle button.active {
background: #4a9eff;
color: white;
}
.view-toggle button:not(:last-child) {
border-right: 1px solid #444;
}
/* Canvas-Bereich */
.canvas-area {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
overflow: auto;
padding: 30px;
background:
linear-gradient(45deg, #1a1a1a 25%, transparent 25%),
linear-gradient(-45deg, #1a1a1a 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #1a1a1a 75%),
linear-gradient(-45deg, transparent 75%, #1a1a1a 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0;
background-color: #1e1e1e;
}
.canvas-frame {
background: white;
border-radius: 8px;
padding: 30px;
box-shadow: 0 8px 40px rgba(0,0,0,0.5);
position: relative;
min-width: 300px;
min-height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
#preview-container {
max-width: 100%;
}
#preview-container svg { max-width: 100%; height: auto; display: block; }
#preview-container canvas { max-width: 100%; height: auto; display: block; }
#preview-container img { max-width: 100%; height: auto; display: block; }
.empty-state {
color: #999;
text-align: center;
padding: 40px;
}
.empty-state .icon { font-size: 3em; margin-bottom: 10px; opacity: 0.3; }
/* ─── Status-Leiste ───────────────── */
.statusbar {
padding: 6px 16px;
background: #1a1a1a;
border-top: 1px solid #333;
font-size: 0.75em;
color: #666;
display: flex;
gap: 20px;
}
.statusbar .status-item span { color: #999; }
/* Spinner */
.spinner {
display: inline-block;
width: 14px; height: 14px;
border: 2px solid #444;
border-top-color: #4a9eff;
border-radius: 50%;
animation: spin 0.6s linear infinite;
vertical-align: middle;
margin-right: 6px;
}
@keyframes spin { to { transform: rotate(360deg); } }
</style>
</head>
<body>
<div class="header">
<h1><span>&#9670;</span> Logo AI Pixel-Perfect Optimizer</h1>
</div>
<div class="app-layout">
<!-- ─── SIDEBAR ─────────────────────────── -->
<div class="sidebar">
<!-- Upload -->
<div class="panel">
<div class="panel-title">Logo laden</div>
<div class="upload-zone" id="upload-zone">
<div class="icon">&#128194;</div>
<div><strong>Logo hierher ziehen</strong></div>
<p>PNG, JPG, SVG oder Font (.otf/.ttf)</p>
</div>
<input type="file" id="logo-input" accept="image/png,image/jpeg,image/svg+xml,.otf,.ttf,.woff">
</div>
<!-- Mathematische Regler -->
<div class="panel">
<div class="panel-title">Exakte Parameter</div>
<div class="control-row">
<div class="control-label">
<span>Buchstabenabstand</span>
<span class="value" id="val-spacing">0 px</span>
</div>
<input type="range" id="spacing" min="-30" max="80" step="0.5" value="0">
</div>
<div class="control-row">
<div class="control-label">
<span>Strichdicke</span>
<span class="value" id="val-thickness">0 px</span>
</div>
<input type="range" id="thickness" min="0" max="8" step="0.1" value="0">
</div>
<div class="control-row">
<div class="control-label">
<span>Skalierung</span>
<span class="value" id="val-scale">100%</span>
</div>
<input type="range" id="scale" min="20" max="200" step="1" value="100">
</div>
<div class="control-row">
<div class="control-label">
<span>Vertikale Stauchung</span>
<span class="value" id="val-flatten">100%</span>
</div>
<input type="range" id="flatten" min="50" max="100" step="1" value="100">
</div>
</div>
<!-- KI-Steuerung -->
<div class="panel ai-section">
<div class="panel-title">KI-Korrektur (exakt, keine Halluzinationen)</div>
<div class="api-row">
<select id="ai-provider">
<option value="openai">OpenAI</option>
<option value="anthropic">Anthropic</option>
</select>
<input type="password" id="ai-apikey" placeholder="API-Key eingeben...">
</div>
<div class="ai-input-area">
<textarea id="ai-prompt" placeholder="Beschreibe exakt, was geändert werden soll, z.B.:&#10;&#10;• Buchstabe 'E' um 10% dicker machen&#10;• Alle Buchstaben 15px weiter auseinander&#10;• Gesamtes Logo 25% kleiner&#10;• Nur den 3. Buchstaben um 5px nach rechts"></textarea>
</div>
<button class="btn-ai" id="btn-ai-apply" disabled>
KI-Korrektur anwenden
</button>
<div class="ai-log" id="ai-log"></div>
</div>
</div>
<!-- ─── HAUPTBEREICH ────────────────────── -->
<div class="main-area">
<!-- Toolbar -->
<div class="toolbar">
<div class="view-toggle">
<button class="active" data-view="result">Ergebnis</button>
<button data-view="original">Original</button>
<button data-view="diff">Vorher / Nachher</button>
</div>
<div class="spacer"></div>
<span class="zoom-info" id="zoom-info">100%</span>
<button class="btn" id="btn-fit">Einpassen</button>
<button class="btn" id="btn-undo">Rückgängig</button>
<button class="btn primary" id="btn-download">Speichern</button>
</div>
<!-- Canvas -->
<div class="canvas-area">
<div class="canvas-frame">
<div id="preview-container">
<div class="empty-state">
<div class="icon">&#9671;</div>
<div>Logo hochladen um zu starten</div>
</div>
</div>
</div>
</div>
<!-- Statusbar -->
<div class="statusbar">
<div class="status-item">Modus: <span id="status-mode"></span></div>
<div class="status-item">Segmente: <span id="status-segments"></span></div>
<div class="status-item">Größe: <span id="status-size"></span></div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>