Mask Sequence Helper
The looping slideshow crossfade scheduler the whole pack is built on
- image_stream
- first_timeline
- second_timeline
- first_text_output
- second_text_output
- total_frames
Mask Sequence Helper is the quiet backbone of the ComfyUI-FrameFX pack. It doesn't draw anything and it doesn't dream - it just takes a stack of images and lays them out into a looping slideshow crossfade, twice, so your animation can hold one image while easing into the next. If you've been poking at the pack's fancier nodes and wondering where all the timing conventions come from, it's this one.
The idea is simple and a little elegant. Every FrameFX node speaks the same language: hold_length frames of stillness, transition_length frames of change, padding_frames of tail. Mask Sequence Helper takes your images and repeats each one for hold_length + transition_length frames - the hold part stays frozen, the transition part is where the next image is waiting to take over.
Two timelines, one crossfade
The trick is that it doesn't build one timeline. It builds first_timeline and second_timeline - the same slideshow shifted by one image. Timeline one is holding image A while timeline two is already showing image B. To crossfade between them you need the mask, and that's what the text outputs are for:
first_text_output- a weight schedule inframe:(1.0),format where timeline one starts fully visible (1.0) and eases to 0.0 across the transition.second_text_output- the mirror image: starts at 0.0, rises to 1.0.
Feed those schedules to whatever mask/weight input your animation stack exposes, wire the two timelines to your image sources, and you've got a clean, looping slideshow where each image holds, fades out as the next fades in, and wraps back to the start. The loop closure is automatic - the last transition leads back into the first image.
The inputs
image_stream- your batch of images (IMAGE).num_images(default 4) - how many of them to use.hold_length(default 5) andtransition_length(default 20) - the timing skeleton. Note the default ratio: holds are short, transitions are long, which suits the Edge-FX animation workflows this pack targets.padding_frames(default 0) - tail frames, held on the last image.
The outputs
first_timeline,second_timeline(IMAGE) - the two offset image sequences.first_text_output,second_text_output(STRING) - theframe:weightmask schedules.total_frames(INT) - everything, including padding. Match your sampler frame count to this and the loop stays whole.
Installing it
Same as the rest of the pack - ComfyUI Manager, search ComfyUI-FrameFX, install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/mgfxer/ComfyUI-FrameFX
Pure Python on top of ComfyUI's bundled torch/PIL - no requirements.txt, no model downloads.
Where people get burned
The frame:(1.0) text format is specific to the animation stack it's meant for - don't assume it'll parse in just any node. If a workflow loads and the mask schedule does nothing, check that the consumer is expecting this exact frame:weight, syntax. And remember that num_images counts frames of the loop, not frames of video - the real video length is num_images × (hold + transition) + padding, which is exactly what total_frames tells you. Trust that output and you'll stay in sync.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image_stream | IMAGE | — | |
| num_images | INT | 4 | — |
| hold_length | INT | 5 | — |
| transition_length | INT | 20 | — |
| padding_frames | INT | 0 | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| first_timeline | IMAGE | — |
| second_timeline | IMAGE | — |
| first_text_output | STRING | — |
| second_text_output | STRING | — |
| total_frames | INT | — |