thats-me/frontend/dev/19-02-2026/umsetzungskonzept.md
2026-03-06 13:56:20 +01:00

14 KiB
Raw Blame History

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: <router-view /> 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 <header> 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 <div> 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.43.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 (<path>) 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 <Transition>
  • 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

{
  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

{
  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/.

;[
  { 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