A11y Graffiti â Schnippsi Stream Session (22.08.25)
Tag: #CRUMB · Session: sess_b93be631e89ad · App: schnippsiâpainter**
Kurzfassung
Wir haben einen barrierearmen GraffitiâSprĂŒhâFlow skizziert, der als OneâLine oder BezierâPfad erfasst, in JSON/SVG/PNG exportiert und live via WebSocket an TouchDesigner / StreamDiffusion gestreamt werden kann. Ziel: Jeder kann ein Textabenteuer âzeichnenâ, GerĂ€teâagnostisch (Pen/Touch/Mouse), mit messbaren Bewegungsdaten fĂŒr Lernâ und A11yâAnwendungen.*
Leitideen
- A11yâFirst: Eingabe per Maus, Touch, Pen; TastaturâShortcuts; klare Kontraste.
- OneâLinerâLogik: Das kleine a (Spirale) im schĂŒtzenden y â als Unterrichtsâ/StoryâAnker (Eule â Baum).
- Messbarkeit: Zeitâ, Druckâ, Winkelâ und GriffâDaten pro Punkt/Anker.
- Offen & leichtgewichtig: Browserbasiert, JSON als TruthâSource, SVG als VektorâArtefakt.
Toolchain (aktuell)
-
Schnippsi Painter
-
Freihand & Bezier (Anker + symmetrische/asymmetrische Griffe)
- Replay, Clear, Export (JSON/SVG/PNG)
- WebSocketâStreaming (Default
ws://localhost:9980) -
Receiver
-
TouchDesigner (WebSocket DAT â JSON â CHOP/TOP)
- Optional: NodeâMockserver zum lokalen Testen
Datenmodell (vereinbart)
Canvas + Session + Liste von Strokes (Freihand oder Bezier). Jeder Punkt trÀgt t (ms), p (Pressure 0..1), tilt und type.
{
"canvas": { "w": 2390, "h": 1214, "dpr": 1 },
"session": { "id": "sess_b93be631e89ad", "app": "schnippsi-painter" },
"strokes": [
{
"id": "st_1755959337193",
"tool": "free",
"colorA": "#62d3a4",
"colorB": "#ffd166",
"width": 12,
"points": [
{ "x": 924, "y": 155.8, "t": 7708, "p": 0.5, "tilt": [0,0], "type": "mouse" }
],
"isBezier": false
},
{
"id": "st_1755959337552",
"tool": "free",
"colorA": "#62d3a4",
"colorB": "#ffd166",
"width": 12,
"points": [
{ "x": 816, "y": 245.8, "t": 8067, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 816, "y": 245.8, "t": 8089, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 816, "y": 247.8, "t": 8098, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 816, "y": 251.8, "t": 8113, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 814, "y": 260.8, "t": 8124, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 812, "y": 265.8, "t": 8134, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 810, "y": 270.8, "t": 8144, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 807, "y": 276.8, "t": 8154, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 802, "y": 286.8, "t": 8164, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 799, "y": 291.8, "t": 8174, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 797, "y": 296.8, "t": 8184, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 794, "y": 300.8, "t": 8193, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 789, "y": 310.8, "t": 8202, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 786, "y": 315.8, "t": 8213, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 782, "y": 321.8, "t": 8224, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 778, "y": 328.8, "t": 8233, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 768, "y": 345.8, "t": 8244, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 761, "y": 355.8, "t": 8253, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 755, "y": 366.8, "t": 8263, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 747, "y": 378.8, "t": 8274, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 731, "y": 401.8, "t": 8283, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 724, "y": 414.8, "t": 8293, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 717, "y": 427.8, "t": 8304, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 711, "y": 440.8, "t": 8313, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 700, "y": 461.8, "t": 8323, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 696, "y": 468.8, "t": 8333, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 693, "y": 472.8, "t": 8342, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 693, "y": 474.8, "t": 8354, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 694, "y": 471.8, "t": 8363, "p": 0.5, "tilt": [0,0], "type": "mouse" },
{ "x": 697, "y": 466.8, "t": 8373, "p": 0.5, "tilt": [0,0], "type": "mouse" }
],
"isBezier": false
}
]
}
Hinweis: FĂŒr BezierâStrokes werden zusĂ€tzlich pro Anker
h1/h2(HandleâVektoren relativ zur AnkerâPosition) gespeichert.
Streaming EventâSchema (Browser â WS)
sessionâ { id, app, ts }strokeStartâ { id, tool, colorA, colorB, width }pointâ { id, x, y, t, p, tilt, type } (Freihand)anchor/anchorsâ { id, x, y, h1:{x,y}, h2:{x,y}, t } (Bezier)strokeEndâ { id, points } (optional: compact)
A11yâNotizen
- TastaturâFirst (B/F/S/R/H), groĂe UIâZiele, hoher Kontrast.
- Geplant: ScreenreaderâHints, BrailleâExport (Punkte als Raster), HaptikâMap fĂŒr PenâTablets, ColorâSafeâPaletten.
NĂ€chste Schritte
- OSCâBridge (WSâOSC) fĂŒr TD & Ableton/Unity.
- PenâDruck & Neigung robust auf iPad/Android.
- BezierâBearbeitung: Anker hinzufĂŒgen/löschen, Pfad segmentweise konvertieren (LineâCurve).
- Datenschutz: ConsentâFlows + Pseudonymisierung im Stream.
- MiniâDemos: EuleâBaumâLevel als interaktives Textabenteuer.
Lizenz / Sharing
CCâBY 4.0 fĂŒr diese Dokumentation. CodeâSnippets MIT, Medien nach jeweiligem Credit.
âDie Eule fliegt wieder zum Baum.â â Jede Frage zĂ€hlt.