# Umsetzungskonzept — "That's Me" Wow-Prototyp Dieses Dokument beschreibt die schrittweise Umsetzung des Prototyps. Jeder Schritt baut auf dem vorherigen auf und ist einzeln testbar. --- ## Phase 1: Viewport & Grundgerüst ### 1.1 — Neues App-Layout (`LifeWaveLayout.vue`) **Ziel:** Minimalistisches Fullscreen-Layout als "Bühne" — ersetzt das bestehende MainLayout für die LifeWave-Ansicht. **Umsetzung:** - Neues Layout `src/layouts/LifeWaveLayout.vue` erstellen - Fullscreen-Viewport (`100dvh`) ohne Quasar-Header/Footer/Drawer - Neutraler Hintergrund: Hell-Modus `#FAFAFA`, Dunkel-Modus `#0A0A0A` - CSS Custom Properties für Theme-Switching (`--bg-primary`, `--bg-glass`, `--text-primary`) - Slot-basiert: `` füllt den gesamten Viewport - Kein Scrolling auf der Hauptebene — alles innerhalb des Viewports **Struktur:** ``` ┌──────────────────────────────┐ │ [User-Icon] top │ ← fixed, z-30 │ │ │ │ │ LifeWave Canvas │ ← absolute, z-0, fullscreen │ + Glow-Punkte │ │ │ │ │ │ [+] bot │ ← fixed, z-30 └──────────────────────────────┘ ``` ### 1.2 — Glassmorphism CSS-System **Ziel:** Wiederverwendbare Glass-Styles als CSS-Klassen (Referenz: die beiden Glassmorphism-Bilder). **Umsetzung:** - In `src/css/app.scss` definieren: - `.glass` — Basis-Glaseffekt (`backdrop-filter: blur(20px)`, halbtransparenter Hintergrund, subtiler Border) - `.glass--panel` — Variante für das Slide-Up-Panel (stärkerer Blur, ~40px) - `.glass--button` — Variante für den schwebenden +-Button - Light/Dark-Mode Varianten über CSS Custom Properties - Subtiler `box-shadow` für Tiefe - 1px Border mit `rgba(255,255,255,0.15)` für den "Glas-Rand" --- ## Phase 2: Header & Navigation ### 2.1 — Header-Leiste **Ziel:** Minimalistischer Header mit Logo links und User-Icon rechts. **Umsetzung:** - Direkt im `LifeWaveLayout.vue` als `
` Element (fixed, z-20) - **Links:** "ThatsMe" als Text-Logo (wird später durch echtes Logo ersetzt). Klick = Dark/Light Mode Toggle (temporär). - **Rechts:** Runder User-Button (40px), `person_outline` Icon, `.glass--button` Styling - Klick öffnet Off-Canvas-Drawer (rechte Seite) - Später: Eingeloggt = Avatar/Initialen mit Glow-Ring ### 2.2 — Floating Action Button "+" (Bottom-Center) **Ziel:** Einzelner schwebender Button zum Erstellen eines neuen Events. **Umsetzung:** - Komponente `src/components/AddEventButton.vue` - Runder Button (56px), positioniert `bottom: 32px; left: 50%; transform: translateX(-50%); position: fixed` - `.glass--button` Styling mit leichtem Glow-Effekt - Material Icon `add` (weiß/grau je nach Theme) - Klick-Animation: leichter Scale-Pulse - Klick öffnet das Event-Panel (Phase 4) --- ## Phase 3: Timeline & Event-Dots ### 3.1 — FloatingLines als optionaler Hintergrund **Ziel:** FloatingLines bleibt als optionales Feature erhalten, ist aber standardmäßig deaktiviert. **Umsetzung:** - FloatingLines im Layout eingebunden mit `v-if="showFloatingLines"` (default: `false`) - Zuschaltbar über Toggle im Off-Canvas-Drawer - Konfiguration: `enabledWaves: ['middle']`, `linesGradient: ['#E94FF5', '#2F4BA2']`, `lineCount: [12]`, `animationSpeed: 0.6` - Dient als Inspiration für die spätere Verbindungslinie (Phase 3.3) ### 3.2 — Scrollbare Timeline mit Glow-Dots **Ziel:** Events als leuchtende Kreise auf einer horizontal scrollbaren Zeitachse darstellen — wie ein visuelles Tagebuch. Referenz: `Bildschirmfoto 2026-02-20 um 10.29.01.png` **Konzept:** - Der Viewport zeigt immer nur einen **Ausschnitt** der Timeline - Die Timeline-Breite berechnet sich aus der Zeitspanne aller Events - Horizontal scrollen (Touch-Swipe / Maus) navigiert durch die Zeit - Unten werden **Monat und Jahr** eingeblendet (aktuell sichtbarer Bereich hervorgehoben) **Umsetzung:** - Neue Komponente `src/components/TimelineView.vue` — der scrollbare Container - Timeline-Container: `overflow-x: auto; overflow-y: hidden; height: 100%` - Innerer Container: Breite berechnet aus Datumsbereich (z.B. 120px pro Monat) - **X-Achse (horizontal):** Datum-basierte Position — jedes Event wird auf seinen exakten Zeitpunkt positioniert - **Y-Achse (vertikal):** Emotionswert (-1 bis +1 → unten bis oben, Mitte = unsichtbare Nulllinie = neutral) - **Monats-Labels:** Am unteren Rand der Timeline, der aktuelle Monat groß/fett, Nachbarmonate kleiner - **Jahres-Label:** Unter den Monaten, wechselt beim Scrollen **GlowDot-Komponente** (`src/components/GlowDot.vue`): - Jeder Punkt ist ein `
` mit radialem CSS-Gradient als "Glow" - Größe: 20-28px Kern - Glow-Farbe durch Emotion ODER Custom-Farbe - Glow-Farblogik: - **Positiv** (> 0): `#FF6B35` (Orange) → `#FFD700` (Gold) → `#4CAF50` (Grün) - **Negativ** (< 0): `#2196F3` (Blau) → `#9C27B0` (Violett) → `#E91E63` (Pink) - **Custom:** User-Farbe überschreibt den Glow, Y-Position bleibt - Klick auf Punkt → öffnet Event-Detail (Phase 5) ### 3.4 — Timeline-Zoom **Ziel:** Der User kann in die Timeline rein- und rauszoomen. Events und Abstände skalieren, Monats-/Jahres-Schriftgrößen bleiben konstant. **Umsetzung:** - `zoomLevel` (0.4–3.0, Default 1.0) multipliziert das `EVENT_SPACING` - GlowDots skalieren via CSS `transform: scale(var(--dot-scale))` über das `zoom`-Prop - **Desktop:** Ctrl+Mausrad oder Trackpad-Pinch (beides feuert `wheel` mit `ctrlKey`) - **Touch:** Zwei-Finger-Pinch-Geste - Scroll-Position bleibt stabil: Der Punkt unter dem Cursor/Pinch-Zentrum bleibt fixiert - Monats- und Jahres-Labels behalten ihre feste Schriftgröße ### 3.3 — Verbindungslinien zwischen Dots **Ziel:** Eine farbverlaufende Linie verbindet die Glow-Punkte und bildet die "LifeWave". Visuell inspiriert durch die FloatingLines-Ästhetik. **Umsetzung:** - SVG-Overlay innerhalb des scrollbaren Timeline-Containers - Cubic Bezier Pfade (``) zwischen den Dots - Gradient entlang des Pfades: Start-Farbe = Glow des linken Dots, End-Farbe = Glow des rechten Dots - Strichbreite: 2-3px, mit `filter: blur(2px)` für weichen Glow - Organisches Feeling: Bezier-Kontrollpunkte leicht versetzt --- ## Phase 4: Neues Event anlegen (Slide-Up Panel) ### 4.1 — Event-Panel Komponente **Ziel:** Glassmorphes Panel fährt von unten hoch. LifeWave bleibt sichtbar und wird durch das "Glas" diffus. **Umsetzung:** - Neue Komponente `src/components/EventPanel.vue` - Positionierung: `position: fixed; bottom: 0; left: 0; right: 0; z-index: 20` - Höhe: ~65% des Viewports (variabel, Drag-Handle zum Resizen optional) - `.glass--panel` Styling (starker Backdrop-Blur ~40px) - Abgerundete obere Ecken (`border-radius: 24px 24px 0 0`) - Slide-Up Animation: `transform: translateY(100%)` → `translateY(0)` mit `transition` oder Vue `` - Kleiner Drag-Handle-Balken oben (visueller Indikator, 40px breit, 4px hoch, zentriert) - **Wichtig:** Hintergrund-LifeWave wird NICHT ausgeblendet — der Glaseffekt erzeugt die Unschärfe ### 4.2 — Event-Formular (Felder im Panel) **Ziel:** Minimalistisches Formular mit Live-Feedback. **Felder:** 1. **Titel** — Textfeld, Placeholder "Was ist passiert?" 2. **Datum** — Date-Picker, Default = heute 3. **Emotions-Regler** — Custom Slider von -1.0 (negativ) bis +1.0 (positiv) - Visuelles Feedback: Slider-Track ändert Farbe (Blau/Kühl ← → Warm/Grün) - Thumb-Farbe passt sich an 4. **Farbe anpassen** (optional) — Toggle + Color-Picker - Default: aus (Emotion bestimmt Farbe) - Es gibt vorgefertigte Farbverläufe für den emotions Leiter hier zum Beispiel Farbkombinationen Verläufe Nagativ -> neutral -> Positiv #FD1D1D -> #FCB045 -> #833AB4 #ED8153 -> #ED8153 -> #217B9E #00D4FF -> #164173 -> #440559 #FDBB2D -> #96BE74 -> #22C1C3 #FC466B -> #9A52B6 -> #3F5EFB #EEAECA -> #C2B4D9 -> #94BBE9 5. **Notiz** — Textarea, optional, 3 Zeilen 6. **Speichern-Button** — Glass-Style, auffällig ### 4.3 — Live-Feedback (Der Wow-Moment) **Ziel:** Während der User das Formular ausfüllt, erscheint in Echtzeit ein neuer Glow-Punkt im Hintergrund. **Umsetzung:** - Sobald das Panel geöffnet wird: ein "Ghost-Dot" (halbtransparent, pulsierend) erscheint auf der Wave - **Emotions-Regler bewegen:** Ghost-Dot wandert auf der Y-Achse nach oben/unten, Glow-Farbe ändert sich live - **Custom-Farbe wählen:** Glow-Farbe ändert sich sofort - **Speichern:** Ghost-Dot wird zum festen Dot (Opacity 1.0, Puls-Animation → statisch), Verbindungslinie animiert sich zum neuen Punkt - Ghost-Dot hat stärkere Puls-Animation als reguläre Dots --- ## Phase 5: Event bearbeiten & Detail-Ansicht ### 5.1 — Event-Detail (Tap auf Glow-Dot) **Ziel:** Tap auf einen Glow-Dot öffnet eine kompakte Detail-Ansicht. **Umsetzung:** - Wiederverwendung des `EventPanel.vue` im "Edit-Modus" - Panel fährt hoch, vorbelegt mit den Event-Daten - Gleiche Felder wie beim Anlegen - Zusätzlich: "Löschen"-Button (dezent, unten im Panel) - Live-Feedback: Änderungen am Emotions-Regler / Farbe ändern den existierenden Dot in Echtzeit ### 5.2 — Dot-Selection-State **Ziel:** Visuelles Feedback welcher Dot ausgewählt ist. **Umsetzung:** - Ausgewählter Dot bekommt: - Vergrößerter Glow (Scale 1.3 mit Transition) - Pulsierender Ring-Effekt (CSS Animation) - Alle anderen Dots werden leicht gedimmt (Opacity 0.5) --- ## Phase 6: Smart-Panel & Einstellungen ### 6.1 — LifeWave-Einstellungen (User-Personalisierung) **Ziel:** Der User kann seine Wave anpassen — das macht die App persönlich. **Umsetzung:** - Im User-Menü (Off-Canvas rechts) unter "Life Wave": - **Wellen-Farben:** Gradient-Picker (2-4 Farben auswählen) - **Wellen-Intensität:** Slider (lineCount: 4-20) - **Wellen-Geschwindigkeit:** Slider (animationSpeed: 0.2-2.0) - **Wellen-Stil:** Auswahl welche Waves aktiv sind (top/middle/bottom) - Änderungen werden live auf die FloatingLines-Props angewendet - Einstellungen im Pinia Store + localStorage persistiert ### 6.2 — Dark/Light Mode Toggle **Ziel:** Nahtloser Wechsel zwischen Hell- und Dunkel-Modus. **Umsetzung:** - Toggle im User-Menü oder als kleines Icon neben dem User-Button - Quasar Dark-Mode Plugin aktivieren (`$q.dark.toggle()`) - CSS Custom Properties wechseln alle Farben - FloatingLines `mixBlendMode` wechselt automatisch - Hintergrundfarbe animiert den Übergang (300ms Transition) --- ## Datenmodell (Pinia Store) ### `src/stores/events.js` ```js { events: [ { id: 'uuid', title: 'Hochzeit von Lisa', date: '2024-06-15', emotion: 0.8, // -1.0 bis +1.0 customColor: null, // null = auto, '#FF00FF' = custom note: 'Wunderschöner Tag im Garten...', createdAt: timestamp, updatedAt: timestamp, }, ] } ``` ### `src/stores/settings.js` ```js { theme: 'light', // 'light' | 'dark' wave: { gradient: ['#E94FF5', '#2F4BA2'], lineCount: 12, speed: 0.6, enabledWaves: ['middle'] } } ``` --- ## Umsetzungsreihenfolge (Arbeitspakete) | # | Paket | Abhängigkeit | Geschätzt | | --- | --------------------------------------- | ------------ | ---------- | | 1 | Phase 1.1 — LifeWaveLayout + Routing | — | Grundlage | | 2 | Phase 1.2 — Glassmorphism CSS | — | Grundlage | | 3 | Phase 3.1 — FloatingLines Fullscreen | #1 | Wow-Basis | | 4 | Phase 2.1 — UserMenuButton | #1, #2 | Navigation | | 5 | Phase 2.2 — AddEventButton | #1, #2 | Navigation | | 6 | Phase 4.1 — EventPanel (Slide-Up, leer) | #2 | Panel | | 7 | Datenmodell — Pinia Stores | — | Daten | | 8 | Phase 3.2 — GlowDots | #3, #7 | Events | | 9 | Phase 3.3 — LifeWavePath (Verbindungen) | #8 | Wave | | 10 | Phase 4.2 — Event-Formular | #6, #7 | Eingabe | | 11 | Phase 4.3 — Live-Feedback (Ghost-Dot) | #8, #10 | Wow! | | 12 | Phase 5 — Event bearbeiten & Detail | #10, #8 | Edit | | 13 | Phase 6.1 — LifeWave-Einstellungen | #3, #7 | Settings | | 14 | Phase 6.2 — Dark/Light Mode | #1 | Theme | --- ## Demo-Daten für den Prototyp 8 Events vorbelegt — 4 mit Bildern, 4 ohne. Bilder liegen in `public/demo/`. ```js ;[ { title: 'Erster Schultag', date: '1995-09-01', emotion: 0.6, image: null }, { title: 'Abiball', date: '2004-06-25', emotion: 0.85, image: 'demo/photo-1530103862676-de8c9debad1d.jpeg', }, { title: 'Trennung', date: '2010-03-15', emotion: -0.7, image: null }, { title: 'Bergwanderung', date: '2014-08-12', emotion: 0.75, image: 'demo/photo-1534067783941-51c9c23ecefd.jpeg', }, { title: 'Jobverlust', date: '2016-11-03', emotion: -0.6, image: null }, { title: 'Hochzeit', date: '2018-07-20', emotion: 0.95, customColor: '#E94FF5', image: 'demo/photo-1506905925346-21bda4d32df4.jpeg', }, { title: 'Umzug', date: '2021-04-01', emotion: -0.3, image: null }, { title: 'Neuer Job', date: '2023-01-10', emotion: 0.5, image: 'demo/photo-1530103862676-de8c9debad1d.jpeg', }, ] ``` --- ## Technische Hinweise - **Three.js** ist bereits als Dependency vorhanden (über FloatingLines.vue) - **Keine neuen Dependencies** nötig für Phase 1-5 (alles mit Quasar + CSS + SVG + Three.js machbar) - **Performance:** GlowDots und LifeWavePath als separate Schicht ÜBER dem WebGL-Canvas (DOM, nicht WebGL) — einfacher zu implementieren, gute Performance bei <50 Events - **Mobile-First:** Alle Maße in `dvh`/`dvw`, Touch-Events für Slider, Panel-Swipe