Skip to content

othaldo/buntzauber

Repository files navigation

Buntzauber

Ruhige, kinderfreundliche Ausmal-App als Flutter-Web/PWA.

Der MVP ist bewusst klein gehalten:

  • Startseite
  • Galerie
  • 1 Demo-Motiv
  • 20 Farben
  • Tap-to-fill auf definierten SVG-Regionen
  • Zoom und Pan in der Ausmalansicht
  • freie Pinsel-Ebene über den SVG-Flächen
  • Undo
  • Reset
  • lokales Speichern im Browser

Es gibt kein Backend, keine Werbung, kein Tracking und keine Accounts.

Lokaler Start

Voraussetzung: Flutter Stable mit Web-Support.

flutter pub get
flutter run -d chrome

Alternativ für einen lokalen Web-Build:

flutter build web

GitHub Pages

Für GitHub Pages sollte der Web-Build mit passendem Base-Href erzeugt werden.

Beispiel für ein Repository buntzauber:

flutter build web --release --base-href /buntzauber/

Danach kann der Inhalt von build/web/ statisch veröffentlicht werden.

Alternativ ist im Repo ein GitHub-Actions-Workflow hinterlegt:

Der Workflow:

  • baut Flutter Web auf jedem Push nach main
  • setzt den base-href automatisch passend für Repo-Pages oder username.github.io
  • veröffentlicht build/web direkt über GitHub Pages

Einmalig in GitHub vorbereiten:

  1. Repository auf GitHub öffnen
  2. Settings -> Pages
  3. Source auf GitHub Actions stellen

Danach reicht ein Push auf main.

Projektstruktur

lib/
  main.dart
  app.dart
  core/
    constants/
    models/
    services/
    theme/
    utils/
  features/
    home/
    gallery/
    coloring/
assets/
  data/
  images/
web/

Technischer Ansatz

Die App nutzt kein Pixel-Flood-Fill.

Stattdessen:

  • jedes Motiv ist ein bewusst vorbereitetes SVG
  • das SVG trennt Füllflächen und schwarze Linien
  • jede ausmalbare Fläche ist eine eigene Region mit ID
  • Regionen werden über ihre SVG-ID erkannt
  • ein Tap prüft, welcher Pfad getroffen wurde
  • danach wird genau diese Region eingefärbt

Die Fortschritte werden mit shared_preferences lokal im Browser gespeichert.

Demo-Motiv

Das erste Demo-Motiv liegt hier:

  • assets/images/demo_flower_meadow.svg
  • assets/data/coloring_pages.json

Die Galerie bezieht ihre Einträge aus assets/data/coloring_pages.json.

Neues Motiv hinzufügen

  1. Neues SVG unter assets/images/ anlegen.
  2. Eintrag in assets/data/coloring_pages.json ergänzen.
  3. App neu starten.

Beispiel für den JSON-Eintrag:

{
  "id": "katze",
  "title": "Katze",
  "svgAsset": "assets/images/katze.svg",
  "overlayAsset": "assets/images/katze_overlay.png"
}

Buntzauber SVG

Das empfohlene Format für schöne und robust ausfüllbare Motive ist ein eigenes, kleines Buntzauber-Schema:

  • Root-SVG mit viewBox
  • eine Gruppe regions
  • optional eine Gruppe outlines
  • in regions liegen nur ausmalbare, geschlossene Flächen
  • in outlines liegen nur die schwarzen Linien

Wichtig:

  • viewBox ist Pflicht
  • ausmalbare Flächen dürfen <path>, <rect>, <circle>, <ellipse>, <polygon> oder <polyline> sein
  • jede Region braucht eine eindeutige id
  • regions ist der kanonische Weg
  • outlines ist optional, aber stark empfohlen
  • keine transform-Ketten einplanen
  • Regionen sollten geschlossen und gut antippbar sein
  • Regionen sollten sich möglichst nicht überlappen
  • kleine, filigrane Miniflächen vermeiden

Warum diese Trennung wichtig ist:

  • die Flächen werden gefüllt
  • die Outlines bleiben sauber oben drüber
  • dadurch sieht das Motiv auch nach vielen Farbwechseln ordentlich aus
  • und wir müssen kein unzuverlässiges Pixel-Flood-Fill auf PNGs bauen

Fallback für Fremd-SVGs:

  • wenn keine data-buntzauber-Marker vorhanden sind, versucht die App einen einfachen Importmodus
  • dabei werden weiß gefüllte Formen als Ausmalflächen interpretiert
  • andere Formen werden als Outline behandelt
  • das ist nur ein pragmatischer Fallback, kein Garant für beliebige Export-SVGs

Minimalbeispiel:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 320">
  <g id="regions" data-buntzauber="regions">
    <rect id="body" x="120" y="140" width="160" height="120" />
    <path id="roof" d="M100 150 L200 80 L300 150 Z" />
  </g>

  <g id="outlines" data-buntzauber="outlines">
    <rect x="120" y="140" width="160" height="120" />
    <path d="M100 150 L200 80 L300 150 Z" />
  </g>
</svg>

Hinweise:

  • Wenn keine outlines definiert sind, zeichnet die App ersatzweise die Regionspfade als Linien.
  • Für kuratierte Motive sollte der Fallback-Modus nicht der Zielweg sein.

Workflow Für Neue Motive

Empfohlener Weg:

  1. Ein Motiv als Referenz oder Lineart erstellen, gern auch mit AI.
  2. Das Motiv in Inkscape, Illustrator oder einem Vektor-Tool sauber vereinfachen.
  3. Eine Ebene für regions bauen: große, geschlossene Flächen eindeutige IDs
  4. Eine zweite Ebene für outlines bauen: schöne schwarze Linien ohne Fülllogik
  5. Als SVG exportieren und in der App testen.

Nicht empfohlen:

  • ein beliebiges PNG direkt zu flood-fillen
  • ein zufälliges SVG aus dem Netz ungeprüft zu importieren
  • nur sichtbare Linien ohne echte Füllflächen zu verwenden

Bild Zu Ausmal-SVG

Der praktikable spätere Weg wird sehr wahrscheinlich so aussehen:

  1. AI oder Illustrator erzeugt ein hübsches Grundmotiv.
  2. Wir vereinfachen die Formensprache für Kinder.
  3. Wir bauen daraus ein Buntzauber-SVG mit regions und outlines.
  4. Die App nutzt dann nur noch diese saubere Version.

Das ist deutlich robuster als:

  • PNG-Flood-Fill
  • Freihand-Malen mit Pinsel
  • heuristische Zufallsimporte von Fremd-SVGs

Sichtbares Lineart PNG Plus Regionen SVG

Die App kann jetzt auch importierte Lineart-Motive nutzen, bei denen zwei Assets zusammenspielen:

  • *_regions.svg Das enthält nur die tappbaren Füllflächen.
  • *_overlay.png Das enthält nur die schwarzen Linien auf transparentem Hintergrund.

In der App werden dann:

  1. die SVG-Regionen unten gefüllt
  2. das transparente Linien-PNG oben drübergelegt

Dadurch können schöne PNG-Ausmalbilder verwendet werden, ohne dass die weißen Bildflächen die Füllfarben überdecken.

PNG Zu Buntzauber-SVG Prototyp

Es gibt jetzt einen ersten Offline-Konverter in Dart:

Er macht aktuell Folgendes:

  1. PNG laden
  2. dunkle Pixel als Outline/Barriere erkennen
  3. Outline leicht verbreitern, um AA-Lücken zu schließen
  4. Flood-Fill auf den hellen Innenflächen
  5. Rand-Hintergrund verwerfen
  6. Regionen als Buntzauber-SVG exportieren

Beispiel:

dart run tool/png_to_buntzauber_svg.dart input.png output.svg \
  --threshold 210 \
  --outline-grow 1 \
  --min-region-pixels 200 \
  --simplify 1.0 \
  --border-regions keep

Für den eigentlichen Import in die Galerie:

dart run tool/import_lineart_png.dart assets/images/haus.png \
  --id haus_png \
  --title "Haus" \
  --threshold 215 \
  --outline-grow 1 \
  --min-region-pixels 200 \
  --simplify 1.0 \
  --border-regions keep

--gap-bridge und --border-snap bleiben standardmäßig aus. Der Standardweg ist jetzt bewusst konservativ: lieber ein stabiler, transparenter Sicherheitsrand rund um das Bild als aggressive Rand-Heuristiken mit Seiteneffekten.

Zusätzlich bleibt standardmäßig ein kleiner Sicherheitsrand von 2px rund um das ganze Bild unfüllbar. Dadurch entsteht kein versehentlicher 1-Pixel-Ring als Region direkt am Canvasrand.

Wenn du mehrere neue Motive gesammelt importieren willst:

  1. PNGs nach assets/import/README.md in assets/import/ legen
  2. Dann einmal ausführen:
dart run tool/import_lineart_folder.dart --scale-factor 2.0

Dabei gilt:

  • Dateiname wird zur Galerie-ID
  • Dateiname wird automatisch in einen Titel umgewandelt
  • --scale-factor vergrößert das PNG vor der Erzeugung von Regionen und Overlay
  • erzeugte Dateien landen in assets/images/
  • assets/data/coloring_pages.json wird aktualisiert

Lokale Import UI

Zusätzlich gibt es jetzt eine kleine lokale Import-Oberfläche neben der eigentlichen App.

Schnellstart vom Repo-Root aus:

dart run tool/import_ui_server.dart

Dann im Browser öffnen:

http://127.0.0.1:8787

Kurzablauf:

  1. PNGs nach assets/import/ legen
  2. dart run tool/import_ui_server.dart starten
  3. http://127.0.0.1:8787 öffnen
  4. Bilder auswählen, scale-factor setzen, importieren

Die Import-UI:

  • liest alle PNGs aus assets/import/
  • zeigt Vorschaubilder und Mehrfachauswahl
  • erlaubt einen gemeinsamen scale-factor
  • importiert nur die ausgewählten Bilder
  • nutzt intern denselben Import-Workflow wie das CLI-Tool

Gut geeignet für:

  • einfache schwarze Lineart auf hellem Hintergrund
  • wenige große Flächen
  • wenig Textur
  • klar geschlossene Formen

Schlecht geeignet für:

  • Fotos
  • starke Schatten
  • weiche Farbverläufe
  • offene Linien
  • sehr detailreiche AI-Bilder ohne Vorverarbeitung

Der Prototyp ist also ein guter Baustein für den späteren Workflow, aber noch kein Wunderkonverter für beliebige Bilder.

MVP-Status

Der aktuelle MVP deckt ab:

  • Startseite mit Einstieg in die Galerie
  • Galerie mit dem Demo-Motiv
  • Ausmalansicht mit 8 Farben
  • Tap-to-fill per SVG-Region
  • Zoom und Pan für kleine Flächen
  • freies Malen als zusätzliche Brush-Layer
  • Undo
  • Reset
  • lokales Wiederherstellen nach Reload

Hinweise

In der aktuellen Arbeitsumgebung war flutter nicht installiert. Deshalb konnte der Build hier nicht lokal ausgeführt werden. Die Projektstruktur und die Dateien sind jedoch so angelegt, dass sie in einer normalen Flutter-Web-Umgebung direkt verwendbar sind.

About

Kleine Mal-App ohne Werbung

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors