textmarquee
textmarquee · sources · schema v1TEXTMARQUEE — a rich-text MARQUEE video GENERATOR (source). MODEL: you type a styled paragraph in the card's tiny rich-text editor (a contenteditable region + a small toolbar); it serializes into a small RICH-TEXT MODEL — an array of paragraphs, each a list of styled RUNS `{ text, bold, italic, underline, color }` + a paragraph `align` (left/center/right), plus a layer FOREGROUND (default glyph colour) + BACKGROUND fill. That model persists in node.data.richText (Y.Doc-synced) and is the single source of truth for BOTH the editor DOM and the video texture. CONTROLS (card): the toolbar = ALIGN left/center/right, BOLD, ITALIC, UNDERLINE, per-character TEXT COLOR (pick a colour for the current selection), and the layer FG + BG colour swatches; below the editor are four knobs (ScrlX/ScrlY/PosX/PosY) and a live preview of the OUT layer. RENDERING: the model is laid out + drawn to an OFFSCREEN 2D canvas with SYSTEM FONTS (real glyphs — system-font text cannot be rasterized in GLSL, so a 2D-canvas→texture upload is the clean path: measure each run in its font/weight/style, draw with per-run colour + underline, honour align + bg fill), uploaded as a WebGL texture, and drawn into the module's FBO at a SCROLL offset + screen POSITION — a 90s-screensaver marquee. A freshly-spawned node renders a "textmarquee" placeholder until you type. I/O: OUT (video) — the rendered scrolling text layer. CV (each port id == param id, linear cvScale so a bipolar ±1 source sweeps the param's full range centred on the knob): ScrlX / ScrlY — horizontal / vertical scroll SPEED (BIPOLAR knob; 0.5 = static, <0.5 scrolls one way, >0.5 the other; the text wraps + re-enters from the opposite edge — a continuous ribbon). PosX / PosY — raw screen POSITION 0..1, CALIBRATED so 0 = text fully off one edge, 1 = fully off the other, 0.5 = centred (drawX = -textWidth + posX*(screenW+textWidth)); with the default-centred knob a bipolar LFO patched into PosX/PosY sweeps the text ALL THE WAY across — fully off the left, through centred, to fully off the right, and back. USAGE: type + style your banner, set FG/BG, then either crawl it with ScrlX/ScrlY (a scrolling marquee) or sweep PosX/PosY from an LFO/sequencer for a CV-driven swoosh; patch OUT into OUTPUT, a video mixer, or any video effect to title/overlay another layer. All ports live on the yellow drill-down PATCH PANEL (no raw side jacks). The pos/scroll/wrap math + the rich-text layout/measurement are pure, unit-tested helpers in $lib/video/modules/textmarquee-layout.
the faceplate
inputs
| id | cable | what it does |
|---|---|---|
scrollX | cv | CV modulating ScrlX — horizontal scroll speed. Bipolar around the knob (0.5 = static): a ±1 source sweeps the full crawl-speed range, scrolling left below centre and right above, with the ribbon wrapping in from the opposite edge. control voltage (CV); modulates scrollX (additive offset — ±1 CV sweeps the full range, centered on the knob) |
scrollY | cv | CV modulating ScrlY — vertical scroll speed. Bipolar around the knob (0.5 = static): a ±1 source sweeps the full speed range, crawling the ribbon up or down and wrapping it back in from the opposite edge. control voltage (CV); modulates scrollY (additive offset — ±1 CV sweeps the full range, centered on the knob) |
posX | cv | CV modulating PosX — the ribbon's raw horizontal position. Calibrated so a default-centred ±1 LFO drives it fully off the left edge, through centre, to fully off the right edge, and back (a complete margin-to-margin sweep). control voltage (CV); modulates posX (additive offset — ±1 CV sweeps the full range, centered on the knob) |
posY | cv | CV modulating PosY — the ribbon's raw vertical position. Calibrated so a default-centred ±1 LFO drives it fully off the top, through centre, to fully off the bottom, and back. control voltage (CV); modulates posY (additive offset — ±1 CV sweeps the full range, centered on the knob) |
outputs
| id | cable | what it does |
|---|---|---|
out | video | The rendered text layer: the styled ribbon drawn at its scrolled position over its background-filled block, with the rest of the frame as layer black. RGB video stream |
params
| id | label | range | default | curve |
|---|---|---|---|---|
scrollX | ScrlX | 0..1 | — | linear |
scrollY | ScrlY | 0..1 | — | linear |
posX | PosX | 0..1 | — | linear |
posY | PosY | 0..1 | — | linear |
controls
| control | what it does |
|---|---|
| PosX | PosX — raw horizontal position, 0..1. 0 places the ribbon fully off the left edge, 1 fully off the right, 0.5 centred. Combined additively with the ScrlX scroll offset. |
| PosY | PosY — raw vertical position, 0..1. 0 places the ribbon fully off the top, 1 fully off the bottom, 0.5 centred. Combined additively with the ScrlY scroll offset. |
| ScrlX | ScrlX — horizontal scroll speed, bipolar 0..1. 0.5 is static (the text sits where PosX/PosY put it); below 0.5 scrolls one way, above 0.5 the other, faster toward the extremes. The ribbon wraps continuously, re-entering from the opposite edge. |
| ScrlY | ScrlY — vertical scroll speed, bipolar 0..1. 0.5 is static; below 0.5 crawls up, above 0.5 crawls down (or vice-versa), faster toward the extremes, wrapping the ribbon back in from the opposite edge. |
source
textmarquee.ts on GitHub.