GIF Text Style
Caption placement without the canvas, by anchor point
- style
Every other way of styling text in this pack wants a mouse. The Multi-Text Designer has a drag canvas, the legacy Text Designer has one too. GIF Text Style has neither - it's a plain widget node that emits a style object, and it exists because "text goes in the top-left corner" is a completely reasonable thing to say without dragging anything.
It's also the node that makes this pack usable in places a canvas isn't: headless batches, API-driven runs, or just a workflow where you'd rather type Bottom Center and be done.
How it works
You pick a position from a ten-item list - the nine familiar anchors (Top Left, Top Center, Top Right, Center Left, Center, Center Right, Bottom Left, Bottom Center, Bottom Right) plus Custom (%). For the anchors, the node places the text box against the frame edges using margin_x and margin_y, measured in pixels of the output frame. That's the part to internalise: this pack resizes your GIF to something like 320 pixels on the long side, so a 16-pixel margin is five percent of the width - visually chunky. The 16 px default is a sensible starting point precisely because the output is small.
For Custom (%), the two margin fields are ignored and the text box is centred on custom_x_percent / custom_y_percent. Note the semantics: those are the centre of the text, not a corner, so 50/50 puts the caption dead centre.
Everything else is the shared styling vocabulary you'll recognise from the rest of the pack - font from your system's font list, size 6–256, colour as a hex string or CSS name, optional rounded background with opacity and corner radius, optional outline with width, optional shadow with X/Y offsets, and line spacing for multi-line text.
The output is a single style (GIF_TEXT_STYLE) socket. It's just a dictionary, and it's interchangeable with what the designer nodes produce - GIF Text Preview and GIF Text Overlay accept either without complaint.
The input that matters, and the output
There's one input, enabled (BOOLEAN, default true), which is the master switch that ends up in the style object and lets everything downstream pass frames through untouched. Then the styling widgets, of which two actually matter on day one: position (default Top Center) and text.
One output: style → GIF Text Preview for a look, and/or GIF Text Overlay to apply it across the batch.
No images input. This node generates a style from nothing, which means you can build the look first and wire the frames up afterwards - handy when you're setting up a workflow and don't have a video selected yet.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/oekobudde/ComfyUI-GIFToolkit.git
Or Manager → search GIF Toolkit. Restart ComfyUI. The pack declares no pip dependencies; ComfyUI-VideoHelperSuite is needed separately for the video-loading half of any workflow you build with it.
Common issues
The margins seem to do nothing. They only apply to the nine anchor positions. On Custom (%) the placement comes from the two percent fields instead.
The preview doesn't match the designer's look. Different node, different defaults - this one labels its colours as CSS names (yellow, black) while the designer uses hex. Same renderer underneath, so once the values match, the pixels match.
Colour is wrong or unchanged after editing. The parser falls back silently on a bad value rather than erroring. #ffff00 and yellow both work; #ff0 and a stray space are less reliable. Retype it.
Nothing renders at the end. Check the enabled toggle here, and then check that the layer text isn't blank - the overlay's fast-exit path returns your frames untouched when there's no text to draw, without any warning.
Inputs (23)
| Name | Type | Default | Description |
|---|---|---|---|
| enabled | BOOLEAN | true | — |
| text | STRING | LET'S GO! | — |
| font | COMBO | DejaVuSans-Bold.ttf | 48 options: PIL Default, DejaVuSansMono-Bold.ttf, DejaVuSerif.ttf, DejaVuSansMono-Oblique.ttf, DejaVuSansMono.ttf, DejaVuSerif-Bold.ttf, +42 |
| font_size | INT | 346–256 | — |
| font_color | STRING | yellow | — |
| position | COMBO | Top Center | 10 options: Top Left, Top Center, Top Right, Center Left, Center, Center Right, +4 |
| margin_x | INT | 160–1024 | — |
| margin_y | INT | 160–1024 | — |
| custom_x_percent | FLOAT | 500–100 | — |
| custom_y_percent | FLOAT | 150–100 | — |
| background_enabled | BOOLEAN | false | — |
| background_color | STRING | black | — |
| background_opacity | INT | 1600–255 | — |
| padding | INT | 80–128 | — |
| corner_radius | INT | 80–128 | — |
| outline_enabled | BOOLEAN | true | — |
| outline_color | STRING | black | — |
| outline_width | INT | 20–32 | — |
| shadow_enabled | BOOLEAN | false | — |
| shadow_color | STRING | black | — |
| shadow_offset_x | INT | 2-64–64 | — |
| shadow_offset_y | INT | 2-64–64 | — |
| line_spacing | INT | 40–64 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| style | GIF_TEXT_STYLE | — |