Nodes/ComfyUI ASCII Art Nodes/Sequential Two-Pass Color Typing
ComfyUI Node

Sequential Two-Pass Color Typing

Type it out in ghost gray, then color it in a second pass

By LamEmil·Created about a year ago·Updated about a year ago· 1
Sequential Two-Pass Color Typing
  • image
  • sequential_two_pass_frames
char_width80
font_pathcour.ttf
font_size15
ascii_charset .'`^":;Il!i~_?[{1(|/fjxnvzXYJCLQ0Zmwqdkh*#M&8%B@$
background_color#000000
initial_text_color#CCCCCC
invert_brightness_mappingfalse
chars_per_frame2
cursor_char_
cursor_blink_frames5
cursor_color#FFFFFF
pause_frames_between_passes10

The newest and most theatrical node in LamEmil's ASCII pack: "Sequential Two-Pass Color Typing" runs the two passes one after the other instead of together. First the entire ASCII art types itself out in a single initial_text_color, blinking cursor and all. Then it pauses. Then a second pass sweeps through and "colors in" each character with its image-sampled color, also under a cursor. Where the concurrent two-pass node chases color with the typing wave, this one holds the whole image in ghost gray and then reveals the picture.

That pause is the whole trick. pause_frames_between_passes (default 10) gives the viewer a beat to register the monochrome outline before the color hits, and that beat is what turns a gimmick into a reveal. This is the most cinematic node in the pack - the one I'd reach for over any of its siblings if the moment matters, like an intro where the full-color image lands as a payoff.

How it works

Mechanically it's two loops over the same flat character map. Pass one draws characters progressively in initial_text_color with a blinking cursor, appending a no-cursor frame when it finishes. If the pause is set, the completed pass-one frame is duplicated pause_frames_between_passes times to hold the reveal. Pass two then redraws the whole grid each frame - characters before its own progress counter get their image-sampled colors, the rest stay in initial_text_color - with a cursor again, ending on a clean final frame. Every frame is rendered with Pillow and upscaled to your input's dimensions, so the output batch is the same size as the input.

The inputs that matter

  • initial_text_color - the ghost color, default #CCCCCC. A mid-gray reads as "placeholder"; pure white is harsher. This node's default is darker than the concurrent version's #FFFFFF, which is the right call for the reveal effect.
  • pause_frames_between_passes - the beat between passes, 0–120. Zero turns it into a plain two-phase animation; 10–20 reads nicely at typical frame rates.
  • chars_per_frame - controls typing speed for both passes (default 2, slightly faster than the other typing nodes). Since pass two retypes over existing characters, a higher value keeps the total runtime sane.
  • cursor_char / cursor_blink_frames / cursor_color - the cursor, present in both passes.

Plus the shared set: char_width, font_path, font_size, ascii_charset, background_color, invert_brightness_mapping. Output is the IMAGE batch sequential_two_pass_frames.

Install and gotchas

ComfyUI Manager (search "ComfyUI ASCII Art Nodes") or:

cd ComfyUI/custom_nodes
git clone https://github.com/LamEmil/ComfyUI_ASCIIArtNode
cd ComfyUI_ASCIIArtNode
pip install -r requirements.txt

Restart after. Only dependency is Pillow. The output batch needs a Video Combine or Save Animated WebP/GIF node downstream - the preview shows frames, but you don't get a file without one.

Pack-wide traps apply: font_path defaults to cour.ttf (not bundled; a missing font degrades to a chunky bitmap - point at a real monospace .ttf), char_width multiplies frame count across two passes plus a pause, so keep it 60–80, and don't rename the cloned folder despite the README's ComfyUI_ASCIINodes naming. It's a tiny single-commit hobby pack with zero community footprint, but of all eight nodes it's the one that feels most like a finished feature.

Categoryimage/animation

Inputs (13)

NameTypeDefaultDescription
imageIMAGE
char_widthINT8010–1000
font_pathSTRINGcour.ttf
font_sizeINT155–100
ascii_charsetSTRING .'`^":;Il!i~_?[{1(|/fjxnvzXYJCLQ0Zmwqdkh*#M&8%B@$
background_colorSTRING#000000
initial_text_colorSTRING#CCCCCC
invert_brightness_mappingBOOLEANfalse
chars_per_frameINT21–100
cursor_charSTRING_
cursor_blink_framesINT51–60
cursor_colorSTRING#FFFFFF
pause_frames_between_passesINT100–120

Outputs (1)

NameTypeDescription
sequential_two_pass_framesIMAGE