1565 lines
75 KiB
HTML
1565 lines
75 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Orfel Viz</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@700&family=Inter:wght@300;400;500;600;700;800&family=Montserrat:wght@400;600;800&family=Orbitron:wght@600;800;900&family=Outfit:wght@400;600;700;800&family=Russo+One&family=Syncopate:wght@700&display=swap" rel="stylesheet">
|
||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||
<link rel="alternate icon" href="favicon.ico">
|
||
<link rel="stylesheet" href="style.css">
|
||
</head>
|
||
<body>
|
||
<div class="app-layout">
|
||
<!-- Header -->
|
||
<header class="app-header">
|
||
<div class="brand">
|
||
<div class="brand-logo">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
||
<polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
|
||
<polyline points="2 17 12 22 22 17"></polyline>
|
||
<polyline points="2 12 12 17 22 12"></polyline>
|
||
</svg>
|
||
</div>
|
||
<div class="brand-text">
|
||
<h1>Orfel Viz</h1>
|
||
<span class="brand-subtitle">Audio Visualizer</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="header-actions">
|
||
<!-- AIWentNonsense Quick Mode Trigger -->
|
||
<button id="btnAiWentNonsenseMode" class="btn btn-aiwentnonsense" title="Aktiviert den AIWentNonsense Brand-Modus mit Logo und Neon-Farben">
|
||
<span class="icon">🤖</span> AIWentNonsense Modus
|
||
</button>
|
||
|
||
<!-- Quick Presets -->
|
||
<div class="quick-preset-picker">
|
||
<label for="quickPresetSelect">Preset:</label>
|
||
<select id="quickPresetSelect">
|
||
</select>
|
||
</div>
|
||
|
||
<button id="headerExportBtn" class="btn btn-primary btn-glow">
|
||
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
|
||
Exportieren
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Main Workspace -->
|
||
<main class="workspace">
|
||
<!-- Left: Stage & Player -->
|
||
<section class="stage-section">
|
||
<!-- Aspect & Tools Bar -->
|
||
<div class="stage-toolbar">
|
||
<div class="aspect-switchers">
|
||
<button class="aspect-btn active" data-aspect="16:9" title="16:9 YouTube Standard (1920x1080 / 4K)">
|
||
<span class="icon">📺</span> 16:9
|
||
</button>
|
||
<button class="aspect-btn" data-aspect="9:16" title="9:16 Shorts, TikTok & Reels (1080x1920)">
|
||
<span class="icon">📱</span> 9:16
|
||
</button>
|
||
<button class="aspect-btn" data-aspect="1:1" title="1:1 Quadratisch (Instagram 1080x1080)">
|
||
<span class="icon">🔲</span> 1:1
|
||
</button>
|
||
</div>
|
||
|
||
<div class="stage-toggles">
|
||
<label class="toggle-chip" title="Zeigt TikTok & Shorts UI-Überlagerung für exaktes Platzieren">
|
||
<input type="checkbox" id="toggleSafeZone">
|
||
<span>Safe-Zone</span>
|
||
</label>
|
||
<label class="toggle-chip" title="Transparenz-Gitter im Hintergrund ein-/ausblenden">
|
||
<input type="checkbox" id="toggleAlphaGrid" checked>
|
||
<span>Alpha-Gitter</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Canvas Viewport -->
|
||
<div class="canvas-viewport" id="canvasViewport">
|
||
<div class="canvas-wrapper aspect-16-9" id="canvasWrapper">
|
||
<canvas id="vizCanvas" width="1920" height="1080"></canvas>
|
||
|
||
<!-- Safe Zone Overlay (Visual helper for Shorts UI) -->
|
||
<div class="safe-zone-overlay hidden" id="safeZoneOverlay">
|
||
<div class="safe-zone-box">
|
||
<div class="safe-zone-title">Shorts / TikTok Safe Area</div>
|
||
<div class="mock-right-buttons">
|
||
<div class="mock-btn">❤️</div>
|
||
<div class="mock-btn">💬</div>
|
||
<div class="mock-btn">↗️</div>
|
||
<div class="mock-disc">💿</div>
|
||
</div>
|
||
<div class="mock-bottom-bar">
|
||
<div class="mock-channel">@DeinChannel</div>
|
||
<div class="mock-song">🎵 Song Title • Original Audio</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Audio Player Controls -->
|
||
<div class="player-bar">
|
||
<div class="player-main-controls">
|
||
<button id="btnPlayPause" class="player-btn-play" title="Play / Pause (Leertaste)">
|
||
<svg id="iconPlay" viewBox="0 0 24 24" width="22" height="22" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
|
||
<svg id="iconPause" class="hidden" viewBox="0 0 24 24" width="22" height="22" fill="currentColor"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>
|
||
</button>
|
||
|
||
<button id="btnRewind" class="player-btn-sub" title="-5 Sekunden">
|
||
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><polyline points="11 17 6 12 11 7"></polyline><polyline points="18 17 13 12 18 7"></polyline></svg>
|
||
</button>
|
||
<button id="btnForward" class="player-btn-sub" title="+5 Sekunden">
|
||
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><polyline points="13 17 18 12 13 7"></polyline><polyline points="6 17 11 12 6 7"></polyline></svg>
|
||
</button>
|
||
|
||
<div class="time-display">
|
||
<span id="currentTime">00:00</span> / <span id="durationTime">00:00</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Waveform / Timeline Scrubber -->
|
||
<div class="timeline-container">
|
||
<input type="range" id="seekScrubber" min="0" max="100" value="0" step="0.1" class="timeline-slider">
|
||
<div class="timeline-progress-bar" id="timelineProgressBar"></div>
|
||
</div>
|
||
|
||
<div class="player-extra-controls">
|
||
<button id="btnLoop" class="player-btn-sub active" title="Audio-Schleife an/aus">
|
||
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><polyline points="17 1 21 5 17 9"></polyline><path d="M3 11V9a4 4 0 0 1 4-4h14"></path><polyline points="7 23 3 19 7 15"></polyline><path d="M21 13v2a4 4 0 0 1-4 4H3"></path></svg>
|
||
</button>
|
||
|
||
<div class="volume-control">
|
||
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"></path></svg>
|
||
<input type="range" id="volumeSlider" min="0" max="1" step="0.05" value="0.9" class="volume-slider">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Right: Inspector & Parameter Controls -->
|
||
<aside class="controls-sidebar">
|
||
<!-- Navigation Tabs -->
|
||
<div class="sidebar-tabs-container">
|
||
<button class="tab-nav-arrow tab-nav-prev hidden" id="tabNavPrev" aria-label="Vorherige Tabs" title="Vorherige Tabs">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>
|
||
</button>
|
||
<nav class="sidebar-tabs" id="sidebarTabs">
|
||
<button class="tab-btn active" data-tab="tab-media">📁 Media</button>
|
||
<button class="tab-btn" data-tab="tab-shape">📐 Form</button>
|
||
<button class="tab-btn" data-tab="tab-spectrum">📊 Spektrum</button>
|
||
<button class="tab-btn" data-tab="tab-fx">✨ FX & 3D</button>
|
||
<button class="tab-btn" data-tab="tab-colors">🎨 Farben</button>
|
||
<button class="tab-btn" data-tab="tab-text">📝 Text</button>
|
||
<button class="tab-btn" data-tab="tab-presets">⚡ Presets</button>
|
||
<button class="tab-btn" data-tab="tab-export">🎬 Export</button>
|
||
</nav>
|
||
<button class="tab-nav-arrow tab-nav-next" id="tabNavNext" aria-label="Nächste Tabs" title="Nächste Tabs">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="sidebar-content">
|
||
<!-- TAB 1: MEDIA -->
|
||
<div class="tab-panel active" id="tab-media">
|
||
<div class="panel-section">
|
||
<h3 class="section-title">1. Audio-Datei (Song)</h3>
|
||
<div class="dropzone" id="audioDropzone">
|
||
<input type="file" id="audioFileInput" accept="audio/*,.wav,.mp3,.flac,.m4a,.ogg" class="file-input-hidden">
|
||
<div class="dropzone-content">
|
||
<svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18V5l12-2v13"></path><circle cx="6" cy="18" r="3"></circle><circle cx="18" cy="16" r="3"></circle></svg>
|
||
<p class="dropzone-text"><strong>WAV / MP3 / FLAC</strong> hierher ziehen</p>
|
||
<span class="dropzone-sub">oder klicken zum Auswählen (bis 200 MB)</span>
|
||
<div class="file-badge hidden" id="audioFileBadge">Kein Song geladen</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">2. Cover-Art / Logo</h3>
|
||
<label class="switch-toggle" title="Cover-Artwork komplett deaktivieren (für reine Wellenformen/No-Cover Visuals)">
|
||
<input type="checkbox" id="showCover" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="coverUploadContainer">
|
||
<div class="dropzone" id="imageDropzone">
|
||
<input type="file" id="imageFileInput" accept="image/*,.png,.jpg,.jpeg,.webp" class="file-input-hidden">
|
||
<div class="dropzone-content">
|
||
<svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg>
|
||
<p class="dropzone-text"><strong>Cover-Bild / Logo</strong> hierher ziehen</p>
|
||
<span class="dropzone-sub">PNG / JPG (wird zentriert maskiert)</span>
|
||
<div class="file-badge hidden" id="imageFileBadge">Standard-Cover</div>
|
||
</div>
|
||
</div>
|
||
<button type="button" id="btnLoadAiWentNonsenseCover" class="btn btn-secondary btn-sm ai-logo-load-btn" style="margin-top: 10px; width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px;">
|
||
<span>🤖</span> AIWentNonsense Logo laden
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<h3 class="section-title">3. Track-Metadaten</h3>
|
||
<div class="form-group">
|
||
<label for="trackTitle">Song-Titel</label>
|
||
<input type="text" id="trackTitle" placeholder="z. B. Du bist mein Käse" value="Dein Songtitel">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="trackArtist">Interpret / Artist</label>
|
||
<input type="text" id="trackArtist" placeholder="z. B. Jannik" value="Artist Name">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB 2: FORM & TOPOLOGIE -->
|
||
<div class="tab-panel" id="tab-shape">
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Visualizer Form & Topologie</h3>
|
||
|
||
<div class="shape-grid-picker">
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="circle" checked>
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">⭕</span>
|
||
<span class="shape-label">Kreis</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="linear">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">➖</span>
|
||
<span class="shape-label">Linear</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="hexagon">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">⬡</span>
|
||
<span class="shape-label">Hexagon</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="diamond">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">💎</span>
|
||
<span class="shape-label">Diamond</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="triangle">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🔺</span>
|
||
<span class="shape-label">Dreieck</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="octagon">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🛑</span>
|
||
<span class="shape-label">Achteck</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="oscilloscope">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">〰️</span>
|
||
<span class="shape-label">Oszilloskop</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="tunnel">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🌀</span>
|
||
<span class="shape-label">3D Tunnel</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="blob">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🧪</span>
|
||
<span class="shape-label">Fluid Blob</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="vumeter">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">📻</span>
|
||
<span class="shape-label">VU-Meter</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="square">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">⏹️</span>
|
||
<span class="shape-label">Quadrat</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="pentagon">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">⬠</span>
|
||
<span class="shape-label">Fünfeck</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="heptagon">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">⬡</span>
|
||
<span class="shape-label">Siebeneck</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="decagon">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🔟</span>
|
||
<span class="shape-label">Zehneck</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="dodecagon">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🕛</span>
|
||
<span class="shape-label">Zwölfeck</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="star">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">⭐</span>
|
||
<span class="shape-label">5-Stern</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="star8">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">✴️</span>
|
||
<span class="shape-label">8-Stern</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="heart">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">💖</span>
|
||
<span class="shape-label">Herz</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="shield">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🛡️</span>
|
||
<span class="shape-label">Schild</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="cross">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">➕</span>
|
||
<span class="shape-label">Kreuz</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="flower">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🌸</span>
|
||
<span class="shape-label">Blume</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="lightning">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">⚡</span>
|
||
<span class="shape-label">Blitz</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="flame">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🔥</span>
|
||
<span class="shape-label">Flamme</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="skull">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">💀</span>
|
||
<span class="shape-label">Totenkopf</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="crown">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">👑</span>
|
||
<span class="shape-label">Krone</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="crescent">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🌙</span>
|
||
<span class="shape-label">Halbmond</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="infinity">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">♾️</span>
|
||
<span class="shape-label">Infinity</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="eye">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">👁️</span>
|
||
<span class="shape-label">Cyber-Auge</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="gem">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">💎</span>
|
||
<span class="shape-label">Diamant</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="pick">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🎸</span>
|
||
<span class="shape-label">Plektrum</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="sun">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">☀️</span>
|
||
<span class="shape-label">Sonne</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="droplet">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">💧</span>
|
||
<span class="shape-label">Tropfen</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="hourglass">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">⏳</span>
|
||
<span class="shape-label">Sanduhr</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="butterfly">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">🦋</span>
|
||
<span class="shape-label">Schmetterling</span>
|
||
</div>
|
||
</label>
|
||
<label class="shape-card">
|
||
<input type="radio" name="shapeType" value="hexagram">
|
||
<div class="shape-card-inner">
|
||
<span class="shape-icon">✡️</span>
|
||
<span class="shape-label">Hexagramm</span>
|
||
</div>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Größe & Bass-Pulse</h3>
|
||
|
||
<div class="control-row">
|
||
<label for="circleRadius">Größe / Radius</label>
|
||
<div class="range-group">
|
||
<input type="range" id="circleRadius" min="40" max="350" value="150" step="1">
|
||
<span class="range-value" id="valCircleRadius">150px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="pulseIntensity">Bass-Pulse Stärke</label>
|
||
<div class="range-group">
|
||
<input type="range" id="pulseIntensity" min="0" max="1" value="0.45" step="0.01">
|
||
<span class="range-value" id="valPulseIntensity">45%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="pulseDecay">Pulse Glättung (Decay)</label>
|
||
<div class="range-group">
|
||
<input type="range" id="pulseDecay" min="0.1" max="0.95" value="0.8" step="0.01">
|
||
<span class="range-value" id="valPulseDecay">80%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Rand & Rahmen</h3>
|
||
<label class="switch-toggle">
|
||
<input type="checkbox" id="showBorder" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="borderOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="borderWidth">Rand-Dicke</label>
|
||
<div class="range-group">
|
||
<input type="range" id="borderWidth" min="1" max="30" value="6" step="1">
|
||
<span class="range-value" id="valBorderWidth">6px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="borderColor">Rand-Farbe</label>
|
||
<input type="color" id="borderColor" value="#ffffff" class="color-picker-input">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Fortschritts-Ring (0-360°)</h3>
|
||
<label class="switch-toggle">
|
||
<input type="checkbox" id="showProgressRing" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="progressRingOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="progressRingColor">Ring-Farbe</label>
|
||
<input type="color" id="progressRingColor" value="#00f0ff" class="color-picker-input">
|
||
</div>
|
||
<div class="control-row">
|
||
<label for="progressRingWidth">Ring-Dicke</label>
|
||
<div class="range-group">
|
||
<input type="range" id="progressRingWidth" min="2" max="20" value="6" step="1">
|
||
<span class="range-value" id="valProgressRingWidth">6px</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Rotation & Drehung</h3>
|
||
|
||
<div class="control-row">
|
||
<label for="rotationSpeed">Vinyl-Drehung (Speed)</label>
|
||
<div class="range-group">
|
||
<input type="range" id="rotationSpeed" min="0" max="20" value="3" step="0.5">
|
||
<span class="range-value" id="valRotationSpeed">3 RPM</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="beatSpinImpulse">Beat-Drehimpuls bei Drops</label>
|
||
<input type="checkbox" id="beatSpinImpulse" checked>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB 3: SPECTRUM -->
|
||
<div class="tab-panel" id="tab-spectrum">
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Audio-Spektrum</h3>
|
||
<label class="switch-toggle" title="Spektrum ein-/ausschalten">
|
||
<input type="checkbox" id="showSpectrum" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="radio-pill-group">
|
||
<label class="radio-pill">
|
||
<input type="radio" name="spectrumMode" value="radial_bars" checked>
|
||
<span>📊 Balken</span>
|
||
</label>
|
||
<label class="radio-pill">
|
||
<input type="radio" name="spectrumMode" value="smooth_wave">
|
||
<span>〰️ Welle</span>
|
||
</label>
|
||
<label class="radio-pill">
|
||
<input type="radio" name="spectrumMode" value="floating_dots">
|
||
<span>✨ Punkte</span>
|
||
</label>
|
||
<label class="radio-pill">
|
||
<input type="radio" name="spectrumMode" value="dual_ring">
|
||
<span>⭕ Dual Ring</span>
|
||
</label>
|
||
<label class="radio-pill">
|
||
<input type="radio" name="spectrumMode" value="block_matrix">
|
||
<span>🧱 Block EQ</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Linear-spezifische Ausrichtung (sichtbar wenn Linear gewählt) -->
|
||
<div class="panel-section" id="linearAlignmentSection">
|
||
<h3 class="section-title">Lineare Horizont-Ausrichtung</h3>
|
||
<select id="linearAlignment" class="select-input">
|
||
<option value="center_mirrored">Symmetrischer Horizont (Oben & Unten)</option>
|
||
<option value="bottom_up">Boden-Equalizer (Von Unten Aufsteigend)</option>
|
||
<option value="top_down">Decken-Equalizer (Von Oben Herabfallend)</option>
|
||
<option value="floating_wave">Frei schwebende Center-Welle</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Geometrie & Dichte</h3>
|
||
|
||
<div class="control-row">
|
||
<label for="barCount">Anzahl Balken / Punkte</label>
|
||
<div class="range-group">
|
||
<input type="range" id="barCount" min="24" max="256" value="96" step="8">
|
||
<span class="range-value" id="valBarCount">96</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="spectrumMaxHeight">Maximale Höhe</label>
|
||
<div class="range-group">
|
||
<input type="range" id="spectrumMaxHeight" min="20" max="400" value="130" step="5">
|
||
<span class="range-value" id="valSpectrumMaxHeight">130px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="barWidth">Balkenbreite</label>
|
||
<div class="range-group">
|
||
<input type="range" id="barWidth" min="1" max="25" value="4" step="0.5">
|
||
<span class="range-value" id="valBarWidth">4px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="barSpacing">Abstand vom Zentrum</label>
|
||
<div class="range-group">
|
||
<input type="range" id="barSpacing" min="0" max="100" value="12" step="1">
|
||
<span class="range-value" id="valBarSpacing">12px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="barCornerRadius">Ecken-Abrundung</label>
|
||
<div class="range-group">
|
||
<input type="range" id="barCornerRadius" min="0" max="10" value="2" step="0.5">
|
||
<span class="range-value" id="valBarCornerRadius">2px</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Frequenz-Analyse</h3>
|
||
|
||
<div class="control-row">
|
||
<label for="freqSensitivity">Empfindlichkeit</label>
|
||
<div class="range-group">
|
||
<input type="range" id="freqSensitivity" min="0.5" max="3.5" value="1.3" step="0.1">
|
||
<span class="range-value" id="valFreqSensitivity">1.3x</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="freqFocus">Frequenz-Fokus</label>
|
||
<select id="freqFocus" class="select-input">
|
||
<option value="balanced">Ausgewogen (Sub bis Höhen)</option>
|
||
<option value="bass_heavy">Basslastig (EDM / Trap)</option>
|
||
<option value="vocal_mid">Mitten & Gesang (Pop / Rock)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="mirrorSpectrum">Spektrum spiegeln (Symmetrisch)</label>
|
||
<input type="checkbox" id="mirrorSpectrum" checked>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- STEREO L/R DUAL-CHANNEL -->
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Stereo L/R Dual-Channel</h3>
|
||
<label class="switch-toggle" title="Echten Stereo-Kanal Split aktivieren">
|
||
<input type="checkbox" id="stereoSplit">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="stereoOptionsContainer" class="hidden">
|
||
<div class="control-row">
|
||
<label for="stereoMode">Kanal-Aufteilung</label>
|
||
<select id="stereoMode" class="select-input">
|
||
<option value="split_hemisphere" selected>Hemisphären-Split (L Links / R Rechts)</option>
|
||
<option value="interleaved">Verschachtelt (L & R alternierend)</option>
|
||
<option value="dual_ring">Dual Ring (L Innen / R Außen)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 3-BAND ELEMENT-ROUTING -->
|
||
<div class="panel-section">
|
||
<h3 class="section-title">3-Band Element-Routing</h3>
|
||
<div class="control-row">
|
||
<label for="routePulse">Center-Pulse Quelle</label>
|
||
<select id="routePulse" class="select-input">
|
||
<option value="sub_bass" selected>Sub-Bass (Kick / 808)</option>
|
||
<option value="mids">Mitten (Vocals / Lead)</option>
|
||
<option value="treble">Höhen (Hi-Hats / Cymbals)</option>
|
||
<option value="full_mix">Gesamter Audio-Mix</option>
|
||
</select>
|
||
</div>
|
||
<div class="control-row">
|
||
<label for="routeParticles">Partikel-Explosion</label>
|
||
<select id="routeParticles" class="select-input">
|
||
<option value="treble" selected>Höhen (Hi-Hats / Snares)</option>
|
||
<option value="sub_bass">Sub-Bass (Kick-Drops)</option>
|
||
<option value="mids">Mitten (Gesang / Lead)</option>
|
||
<option value="full_mix">Gesamter Audio-Mix</option>
|
||
</select>
|
||
</div>
|
||
<div class="control-row">
|
||
<label for="routeShake">Bass-Shake Quelle</label>
|
||
<select id="routeShake" class="select-input">
|
||
<option value="sub_bass" selected>Sub-Bass (Tiefe Kicks)</option>
|
||
<option value="mids">Mitten (Synth-Drops)</option>
|
||
<option value="full_mix">Gesamter Audio-Mix</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- BPM & BEAT-SYNCHRONISATION -->
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">BPM & Beat-Synchronisation</h3>
|
||
<label class="switch-toggle" title="Vinyl-Drehung, Grid und Puls an Song-BPM koppeln">
|
||
<input type="checkbox" id="bpmSync">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="bpmOptionsContainer" class="hidden">
|
||
<div class="control-row">
|
||
<label for="bpmValue">Song-Tempo (BPM)</label>
|
||
<div class="bpm-input-wrapper">
|
||
<input type="number" id="bpmValue" min="40" max="260" value="128" step="1" class="bpm-num-input">
|
||
<span class="bpm-badge" id="bpmDetectedBadge">Auto-Detect</span>
|
||
<button type="button" id="btnTapTempo" class="btn btn-secondary btn-sm" title="Im Takt mehrfach klicken">Tap</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="bpmSyncRotation">Vinyl-Drehung im Beat synchronisieren</label>
|
||
<input type="checkbox" id="bpmSyncRotation" checked>
|
||
</div>
|
||
<div class="toggle-row">
|
||
<label for="bpmSyncGrid">3D Grid-Flug synchronisieren</label>
|
||
<input type="checkbox" id="bpmSyncGrid" checked>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB 4: FX & 3D -->
|
||
<div class="tab-panel" id="tab-fx">
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Partikel-System</h3>
|
||
<label class="switch-toggle">
|
||
<input type="checkbox" id="enableParticles" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="particleOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="particleType">Partikel-Typ</label>
|
||
<select id="particleType" class="select-input">
|
||
<option value="starfield">3D Warp Starfield (Kameraflug)</option>
|
||
<option value="dust">Schwebender Staub (Floating Dust)</option>
|
||
<option value="sparks">Audio-Funken (Reactive Sparks)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="particleCount">Partikel-Anzahl</label>
|
||
<div class="range-group">
|
||
<input type="range" id="particleCount" min="20" max="300" value="100" step="10">
|
||
<span class="range-value" id="valParticleCount">100</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="particleSpeed">Geschwindigkeit</label>
|
||
<div class="range-group">
|
||
<input type="range" id="particleSpeed" min="0.2" max="4.0" value="1.0" step="0.1">
|
||
<span class="range-value" id="valParticleSpeed">1.0x</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="particleWarp">Warp-Explosion bei Drops</label>
|
||
<div class="range-group">
|
||
<input type="range" id="particleWarp" min="0" max="6.0" value="2.5" step="0.2">
|
||
<span class="range-value" id="valParticleWarp">2.5x</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">3D Synthwave Grid Floor</h3>
|
||
<label class="switch-toggle" title="Retro-Perspektiven-Gitterboden aktivieren">
|
||
<input type="checkbox" id="enableGrid">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="gridOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="colorGrid">Grid-Farbe</label>
|
||
<input type="color" id="colorGrid" value="#ff007f" class="color-picker-input">
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="gridPerspective">Gitter-Perspektive (Horizont)</label>
|
||
<div class="range-group">
|
||
<input type="range" id="gridPerspective" min="0.3" max="0.9" value="0.65" step="0.05">
|
||
<span class="range-value" id="valGridPerspective">65%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="gridAudioReactive">Audio-Reaktivität</label>
|
||
<div class="range-group">
|
||
<input type="range" id="gridAudioReactive" min="0" max="1.0" value="0.5" step="0.05">
|
||
<span class="range-value" id="valGridAudioReactive">50%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Kamera & Beat-Effekte</h3>
|
||
|
||
<div class="toggle-row">
|
||
<label for="enableShake">Bass-Shake (Kamera-Erschütterung)</label>
|
||
<input type="checkbox" id="enableShake" checked>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="camShakeIntensity">Shake-Intensität</label>
|
||
<div class="range-group">
|
||
<input type="range" id="camShakeIntensity" min="0" max="1.0" value="0.35" step="0.05">
|
||
<span class="range-value" id="valCamShakeIntensity">35%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="enableGlitch">RGB-Split / Glitch bei Drops</label>
|
||
<input type="checkbox" id="enableGlitch" checked>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="rgbSplitIntensity">Glitch-Stärke</label>
|
||
<div class="range-group">
|
||
<input type="range" id="rgbSplitIntensity" min="0" max="1.0" value="0.25" step="0.05">
|
||
<span class="range-value" id="valRgbSplitIntensity">25%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="beatFlash">Beat-Flash (Strobe-Effekt bei Kicks)</label>
|
||
<input type="checkbox" id="beatFlash">
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="enableBassZoom">Kamera Bass-Zoom (Pulsierender Viewport)</label>
|
||
<input type="checkbox" id="enableBassZoom" checked>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- RETRO VHS & SCANLINES -->
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Retro VHS & Scanlines</h3>
|
||
<label class="switch-toggle" title="Vintage VHS/CRT-Effekt aktivieren">
|
||
<input type="checkbox" id="enableVhs">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="vhsOptionsContainer" class="hidden">
|
||
<div class="control-row">
|
||
<label for="vhsScanlineIntensity">Scanline-Dichte / Deckkraft</label>
|
||
<div class="range-group">
|
||
<input type="range" id="vhsScanlineIntensity" min="0.05" max="0.6" value="0.25" step="0.05">
|
||
<span class="range-value" id="valVhsScanlineIntensity">25%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="vhsNoiseIntensity">VHS Bandrauschen & Jitter</label>
|
||
<div class="range-group">
|
||
<input type="range" id="vhsNoiseIntensity" min="0" max="0.5" value="0.15" step="0.05">
|
||
<span class="range-value" id="valVhsNoiseIntensity">15%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="vhsCrtCurvature">CRT Bildschirm-Vignette & Krümmung</label>
|
||
<input type="checkbox" id="vhsCrtCurvature" checked>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- PHOSPHOR AFTERGLOW / TRAILS -->
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Phosphor Afterglow (Schweif)</h3>
|
||
<label class="switch-toggle" title="Nachleucht-Schweif wie bei Analog-Oszilloskopen">
|
||
<input type="checkbox" id="enableAfterglow">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="afterglowOptionsContainer" class="hidden">
|
||
<div class="control-row">
|
||
<label for="afterglowDecay">Schweif-Länge (Decay)</label>
|
||
<div class="range-group">
|
||
<input type="range" id="afterglowDecay" min="0.5" max="0.96" value="0.82" step="0.02">
|
||
<span class="range-value" id="valAfterglowDecay">82%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="afterglowMode">Phosphor-Farbtönung</label>
|
||
<select id="afterglowMode" class="select-input">
|
||
<option value="original" selected>Original Visualizer-Farbe</option>
|
||
<option value="green_p1">Classic Radar (P1 Phosphor Grün)</option>
|
||
<option value="amber_p4">Vintage Amber (P4 Warm-Gold)</option>
|
||
<option value="cyan_neon">Cyberpunk Cyan</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB 5: COLORS & NEON GLOW -->
|
||
<div class="tab-panel" id="tab-colors">
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Kuratierte Farbpaletten</h3>
|
||
<div class="palette-quick-grid">
|
||
<button class="palette-chip" data-p1="#00f0ff" data-p2="#ff007f" data-p3="#8030e0" title="AIWentNonsense Signature">
|
||
<span class="palette-preview" style="background: linear-gradient(135deg, #00f0ff, #ff007f, #8030e0);"></span>
|
||
<span>🤖 AIWentNonsense</span>
|
||
</button>
|
||
<button class="palette-chip" data-p1="#00f0ff" data-p2="#ff007f" data-p3="#7000ff" title="Cyberpunk Neon">
|
||
<span class="palette-preview" style="background: linear-gradient(135deg, #00f0ff, #ff007f, #7000ff);"></span>
|
||
<span>Cyberpunk</span>
|
||
</button>
|
||
<button class="palette-chip" data-p1="#ff7700" data-p2="#ff0055" data-p3="#7900ff" title="Synthwave Sunset">
|
||
<span class="palette-preview" style="background: linear-gradient(135deg, #ff7700, #ff0055, #7900ff);"></span>
|
||
<span>Synthwave</span>
|
||
</button>
|
||
<button class="palette-chip" data-p1="#00ff88" data-p2="#00e5ff" data-p3="#0055ff" title="Toxic Emerald">
|
||
<span class="palette-preview" style="background: linear-gradient(135deg, #00ff88, #00e5ff, #0055ff);"></span>
|
||
<span>Emerald</span>
|
||
</button>
|
||
<button class="palette-chip" data-p1="#00e1ff" data-p2="#ffffff" data-p3="#0051ff" title="Ice Blade">
|
||
<span class="palette-preview" style="background: linear-gradient(135deg, #00e1ff, #ffffff, #0051ff);"></span>
|
||
<span>Ice Blade</span>
|
||
</button>
|
||
<button class="palette-chip" data-p1="#ffcc00" data-p2="#ff3300" data-p3="#880000" title="Fire Amber">
|
||
<span class="palette-preview" style="background: linear-gradient(135deg, #ffcc00, #ff3300, #880000);"></span>
|
||
<span>Fire Amber</span>
|
||
</button>
|
||
<button class="palette-chip" data-p1="#bf00ff" data-p2="#e066ff" data-p3="#3b0066" title="Royal Violet">
|
||
<span class="palette-preview" style="background: linear-gradient(135deg, #bf00ff, #e066ff, #3b0066);"></span>
|
||
<span>Royal Violet</span>
|
||
</button>
|
||
<button class="palette-chip" data-p1="#ffffff" data-p2="#aaaaaa" data-p3="#555555" title="Monochrome Clean">
|
||
<span class="palette-preview" style="background: linear-gradient(135deg, #ffffff, #aaaaaa, #555555);"></span>
|
||
<span>Monochrome</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Farbverlaufs-Editor</h3>
|
||
|
||
<div class="control-row">
|
||
<label for="colorMode">Farb-Modus</label>
|
||
<select id="colorMode" class="select-input">
|
||
<option value="gradient_2">2-Farben Verlauf</option>
|
||
<option value="gradient_3">3-Farben Verlauf</option>
|
||
<option value="rainbow">Regenbogen / Chroma Beat-Loop</option>
|
||
<option value="solid">Einfarbig (Solid)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="color-picker-row">
|
||
<div class="color-picker-item">
|
||
<label for="colorGrad1">Farbe 1</label>
|
||
<input type="color" id="colorGrad1" value="#00f0ff" class="color-picker-input">
|
||
</div>
|
||
<div class="color-picker-item" id="colorGrad2Item">
|
||
<label for="colorGrad2">Farbe 2</label>
|
||
<input type="color" id="colorGrad2" value="#ff007f" class="color-picker-input">
|
||
</div>
|
||
<div class="color-picker-item" id="colorGrad3Item">
|
||
<label for="colorGrad3">Farbe 3</label>
|
||
<input type="color" id="colorGrad3" value="#7000ff" class="color-picker-input">
|
||
</div>
|
||
<div class="color-picker-item">
|
||
<label for="colorParticle">Partikel</label>
|
||
<input type="color" id="colorParticle" value="#ffffff" class="color-picker-input">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="gradientStyle">Verlauf-Geometrie</label>
|
||
<select id="gradientStyle" class="select-input">
|
||
<option value="angular">360° Winkelverlauf (Radial Conic)</option>
|
||
<option value="radial">Zentrum zu Rand (Linear Radial)</option>
|
||
<option value="linear_h">Horizontal (Links nach Rechts)</option>
|
||
<option value="linear_v">Vertikal (Oben nach Unten)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Neon Bloom & Glow Engine</h3>
|
||
<label class="switch-toggle" title="Neon-Glow aktivieren">
|
||
<input type="checkbox" id="enableGlow" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="glowOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="glowIntensity">Glow-Leuchtkraft</label>
|
||
<div class="range-group">
|
||
<input type="range" id="glowIntensity" min="0" max="1.0" value="0.75" step="0.05">
|
||
<span class="range-value" id="valGlowIntensity">75%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="glowBlur">Glow-Radius (Bloom Spread)</label>
|
||
<div class="range-group">
|
||
<input type="range" id="glowBlur" min="0" max="60" value="25" step="2">
|
||
<span class="range-value" id="valGlowBlur">25px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="laserCore">Doppelter Laser-Kern (Laser Core Line)</label>
|
||
<input type="checkbox" id="laserCore" checked>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Hintergrund-Modus</h3>
|
||
<select id="backgroundMode" class="select-input">
|
||
<option value="transparent">100% Transparent (Alpha-Kanal für DaVinci Resolve)</option>
|
||
<option value="blurred_cover">Unscharfes Cover-Artwork im Hintergrund</option>
|
||
<option value="dark_vignette">Dunkle Obsidian-Vignette</option>
|
||
<option value="solid_black">Reines Schwarz (#000000)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB 6: TYPOGRAPHY & OVERLAY -->
|
||
<div class="tab-panel" id="tab-text">
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Song-Info Overlay</h3>
|
||
<label class="switch-toggle" title="Gesamtes Text-Overlay an/aus">
|
||
<input type="checkbox" id="showTextOverlay" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="textOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="fontFamily">Schriftart</label>
|
||
<select id="fontFamily" class="select-input">
|
||
<option value="'Outfit', sans-serif">Outfit (Modern Clean)</option>
|
||
<option value="'Orbitron', sans-serif">Orbitron (Cyber / EDM)</option>
|
||
<option value="'Syncopate', sans-serif">Syncopate (Futuristic Wide)</option>
|
||
<option value="'Montserrat', sans-serif">Montserrat (Bold Studio)</option>
|
||
<option value="'Russo One', sans-serif">Russo One (Heavy Impact)</option>
|
||
<option value="'Inter', sans-serif">Inter (Minimalist)</option>
|
||
<option value="'Cinzel', serif">Cinzel (Cinematic Serif)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="textPosition">Position</label>
|
||
<select id="textPosition" class="select-input">
|
||
<option value="below_circle" selected>Unter der Form</option>
|
||
<option value="above_circle">Über der Form</option>
|
||
<option value="bottom_center">Unten Zentriert</option>
|
||
<option value="top_center">Oben Zentriert</option>
|
||
<option value="center_inside">In der Mitte</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="textOffsetY">Vertikaler Feinabstand (Y-Offset)</label>
|
||
<div class="range-group">
|
||
<input type="range" id="textOffsetY" min="-300" max="300" value="0" step="5">
|
||
<span class="range-value" id="valTextOffsetY">0px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="textSpacing">Zeilenabstand</label>
|
||
<div class="range-group">
|
||
<input type="range" id="textSpacing" min="0" max="40" value="10" step="2">
|
||
<span class="range-value" id="valTextSpacing">10px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="textPulseWithBeat">Text pulsiert im Beat</label>
|
||
<input type="checkbox" id="textPulseWithBeat" checked>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="textGlow">Neon-Glow für Schrift</label>
|
||
<input type="checkbox" id="textGlow">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- SONG TITEL -->
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Song-Titel</h3>
|
||
<label class="switch-toggle" title="Titel anzeigen">
|
||
<input type="checkbox" id="showTrackTitle" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="titleOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="titleFontSize">Schriftgröße</label>
|
||
<div class="range-group">
|
||
<input type="range" id="titleFontSize" min="14" max="90" value="38" step="2">
|
||
<span class="range-value" id="valTitleFontSize">38px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="titleColor">Textfarbe</label>
|
||
<input type="color" id="titleColor" value="#ffffff" class="color-picker-input">
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="titleFontWeight">Schriftstärke</label>
|
||
<select id="titleFontWeight" class="select-input">
|
||
<option value="900">Black (900)</option>
|
||
<option value="700" selected>Bold (700)</option>
|
||
<option value="600">SemiBold (600)</option>
|
||
<option value="400">Regular (400)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="titleUppercase">Nur Großbuchstaben (ALL CAPS)</label>
|
||
<input type="checkbox" id="titleUppercase">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ARTIST / INTERPRET -->
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Artist / Interpret</h3>
|
||
<label class="switch-toggle" title="Artist anzeigen">
|
||
<input type="checkbox" id="showTrackArtist" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="artistOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="artistFontSize">Schriftgröße</label>
|
||
<div class="range-group">
|
||
<input type="range" id="artistFontSize" min="10" max="60" value="22" step="2">
|
||
<span class="range-value" id="valArtistFontSize">22px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="artistColor">Textfarbe</label>
|
||
<input type="color" id="artistColor" value="#cccccc" class="color-picker-input">
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="artistFontWeight">Schriftstärke</label>
|
||
<select id="artistFontWeight" class="select-input">
|
||
<option value="700">Bold (700)</option>
|
||
<option value="600">SemiBold (600)</option>
|
||
<option value="500" selected>Medium (500)</option>
|
||
<option value="400">Regular (400)</option>
|
||
<option value="300">Light (300)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="toggle-row">
|
||
<label for="artistUppercase">Nur Großbuchstaben (ALL CAPS)</label>
|
||
<input type="checkbox" id="artistUppercase">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TIMECODE -->
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Live Timecode</h3>
|
||
<label class="switch-toggle" title="Timecode anzeigen">
|
||
<input type="checkbox" id="showTimecode" checked>
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="timecodeOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="timecodeFontSize">Schriftgröße</label>
|
||
<div class="range-group">
|
||
<input type="range" id="timecodeFontSize" min="10" max="36" value="16" step="1">
|
||
<span class="range-value" id="valTimecodeFontSize">16px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="timecodeColor">Farbe</label>
|
||
<input type="color" id="timecodeColor" value="#00f0ff" class="color-picker-input">
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="timecodeMode">Format</label>
|
||
<select id="timecodeMode" class="select-input">
|
||
<option value="elapsed_and_total" selected>Aktuell / Gesamt (01:23 / 03:45)</option>
|
||
<option value="elapsed_only">Nur Aktuell (01:23)</option>
|
||
<option value="remaining">Verbleibend (-02:22)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- LINEAR PROGRESS BAR -->
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Linearer Fortschrittsbalken</h3>
|
||
<label class="switch-toggle" title="Fortschrittsbalken anzeigen">
|
||
<input type="checkbox" id="showProgressBar">
|
||
<span class="switch-slider"></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="progressBarOptionsContainer">
|
||
<div class="control-row">
|
||
<label for="progressBarWidth">Balken-Breite</label>
|
||
<div class="range-group">
|
||
<input type="range" id="progressBarWidth" min="100" max="800" value="380" step="10">
|
||
<span class="range-value" id="valProgressBarWidth">380px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="progressBarHeight">Balken-Höhe</label>
|
||
<div class="range-group">
|
||
<input type="range" id="progressBarHeight" min="2" max="16" value="4" step="1">
|
||
<span class="range-value" id="valProgressBarHeight">4px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="control-row">
|
||
<label for="progressBarColor">Fortschritts-Farbe</label>
|
||
<input type="color" id="progressBarColor" value="#00f0ff" class="color-picker-input">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB 7: PRESETS -->
|
||
<div class="tab-panel" id="tab-presets">
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Presets</h3>
|
||
|
||
<div class="preset-cards-grid">
|
||
<!-- AIWentNonsense Presets -->
|
||
<button class="preset-select-btn preset-btn-highlight" data-preset="aiwentnonsense">
|
||
<span class="preset-icon">🤖</span>
|
||
<div class="preset-btn-info">
|
||
<strong>AIWentNonsense</strong>
|
||
<span class="preset-badge-tag">Official Brand</span>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn preset-btn-highlight" data-preset="aiwentnonsense_dark">
|
||
<span class="preset-icon">🔮</span>
|
||
<div class="preset-btn-info">
|
||
<strong>AIWentNonsense Dark</strong>
|
||
<span class="preset-badge-tag">Nebula Mode</span>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn preset-btn-highlight" data-preset="aiwentnonsense_overdrive">
|
||
<span class="preset-icon">⚡</span>
|
||
<div class="preset-btn-info">
|
||
<strong>AIWentNonsense Overdrive</strong>
|
||
<span class="preset-badge-tag">Heavy Drop</span>
|
||
</div>
|
||
</button>
|
||
|
||
<!-- Classic Signature Presets -->
|
||
<button class="preset-select-btn" data-preset="trap_nation">
|
||
<span class="preset-icon">🟣</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Trap Nation</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="ncs_electro">
|
||
<span class="preset-icon">🟡</span>
|
||
<div class="preset-btn-info">
|
||
<strong>NCS Electro</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="synthwave_horizon">
|
||
<span class="preset-icon">🌅</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Synthwave Horizon</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="laser_oscilloscope">
|
||
<span class="preset-icon">〰️</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Laser Oscilloscope</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="diamond_bass">
|
||
<span class="preset-icon">💎</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Diamond Bass</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="cosmic_wormhole">
|
||
<span class="preset-icon">🌀</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Cosmic Wormhole</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="studio_rack_eq">
|
||
<span class="preset-icon">📊</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Studio Graphic EQ</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="minimal_ice_wave">
|
||
<span class="preset-icon">❄️</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Minimal Ice Wave</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="toxic_emerald">
|
||
<span class="preset-icon">🔺</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Toxic Emerald</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="solar_flare">
|
||
<span class="preset-icon">🛑</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Solar Flare</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="cyberpunk_city">
|
||
<span class="preset-icon">🏙️</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Cyberpunk City</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="monochrome_cinema">
|
||
<span class="preset-icon">🎬</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Monochrome Cinema</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="retro_cassette">
|
||
<span class="preset-icon">📼</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Retro Cassette</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="deep_space_nebula">
|
||
<span class="preset-icon">🌌</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Deep Space Nebula</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="glitch_overdrive">
|
||
<span class="preset-icon">⚡</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Glitch Overdrive</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="liquid_ambient">
|
||
<span class="preset-icon">💧</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Liquid Ambient</strong>
|
||
</div>
|
||
</button>
|
||
|
||
<!-- New Creative Presets -->
|
||
<button class="preset-select-btn" data-preset="hyper_aurora">
|
||
<span class="preset-icon">🌌</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Hyper Aurora</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="volcanic_magma">
|
||
<span class="preset-icon">🌋</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Volcanic Magma</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="neon_matrix">
|
||
<span class="preset-icon">🟩</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Neon Matrix</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="sunset_lofi">
|
||
<span class="preset-icon">🌇</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Sunset Lo-Fi Chill</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="phantom_white">
|
||
<span class="preset-icon">⚪</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Phantom Pure White</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="midnight_tokyo">
|
||
<span class="preset-icon">🌸</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Midnight Tokyo</strong>
|
||
</div>
|
||
</button>
|
||
<button class="preset-select-btn" data-preset="galaxy_pulsar">
|
||
<span class="preset-icon">🪐</span>
|
||
<div class="preset-btn-info">
|
||
<strong>Galaxy Pulsar</strong>
|
||
</div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Eigene Presets</h3>
|
||
<div class="preset-manager-controls">
|
||
<button type="button" id="btnSavePreset" class="btn btn-secondary btn-sm">Speichern</button>
|
||
<button type="button" id="btnExportPresetJson" class="btn btn-secondary btn-sm">Exportieren (.json)</button>
|
||
<button type="button" id="btnImportPresetJson" class="btn btn-secondary btn-sm">Importieren (.json)</button>
|
||
<input type="file" id="importPresetInput" accept=".json" class="file-input-hidden">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB 8: VIDEO EXPORT -->
|
||
<div class="tab-panel" id="tab-export">
|
||
<div class="panel-section">
|
||
<h3 class="section-title">Video Export</h3>
|
||
|
||
<div class="export-engine-badge" id="exportEngineBadge">
|
||
<span class="badge-icon">⚡</span>
|
||
<div class="badge-content">
|
||
<strong id="exportEngineTitle">Multi-Format Server Export</strong>
|
||
<span id="exportEngineDesc">Rendert automatisch ProRes, WebM Alpha, QTRLE und MP4 im Hintergrund.</span>
|
||
</div>
|
||
</div>
|
||
|
||
<input type="hidden" id="exportFormat" value="prores">
|
||
|
||
<div class="form-row-2">
|
||
<div class="form-group">
|
||
<label for="exportResolution">Auflösung</label>
|
||
<select id="exportResolution" class="select-input">
|
||
<option value="1080p" selected>1080p Full HD</option>
|
||
<option value="4k">4K Ultra HD (2160p)</option>
|
||
<option value="720p">720p HD</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="exportFps">Bildrate</label>
|
||
<select id="exportFps" class="select-input">
|
||
<option value="60" selected>60 FPS</option>
|
||
<option value="30">30 FPS</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Video Render Button -->
|
||
<button id="btnStartExport" class="btn btn-primary btn-large btn-glow">
|
||
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
|
||
Video rendern & downloaden
|
||
</button>
|
||
|
||
<!-- Progress Card -->
|
||
<div class="export-progress-card hidden" id="exportProgressCard">
|
||
<div class="progress-header">
|
||
<span id="exportStatusText">Rendert Video...</span>
|
||
<span id="exportPercent">0%</span>
|
||
</div>
|
||
<div class="progress-bar-track">
|
||
<div class="progress-bar-fill" id="exportProgressBarFill"></div>
|
||
</div>
|
||
<div class="progress-meta">
|
||
<span id="exportFpsLive">Status: Rendert...</span>
|
||
<span id="exportEta">Verbleibend: --</span>
|
||
</div>
|
||
<button id="btnCancelExport" class="btn btn-secondary btn-sm" style="margin-top: 8px;">Abbrechen</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Render History Section -->
|
||
<div class="panel-section">
|
||
<div class="section-header-with-toggle">
|
||
<h3 class="section-title">Render Verlauf</h3>
|
||
<button id="btnRefreshHistory" class="btn btn-secondary btn-sm" title="Verlauf aktualisieren">
|
||
🔄
|
||
</button>
|
||
</div>
|
||
<div class="export-history-list" id="exportHistoryList">
|
||
<div class="empty-state">Noch keine Renderings im Verlauf.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
</main>
|
||
</div>
|
||
|
||
<script src="mp4-muxer.js"></script>
|
||
<script src="webm-muxer.js"></script>
|
||
<script src="app.js"></script>
|
||
</body>
|
||
</html>
|