Animated Shape Mask
Procedural mask reveals, no drawing required
- IMAGE
- num_shades
- width
- height
Animating a mask is one of those things that sounds easy until you try it - you need a moving region that changes every frame, and drawing 64 of them by hand is miserable. Animated Shape Mask is the cheat code: it generates a whole mask animation procedurally from a handful of parameters. Moving bands, traveling sine waves, expanding or contracting circles - pick a mode, pick a resolution, and out comes an image sequence where each frame is a mask you can drive an inpainting reveal with.
This is the sibling of Animation_RGB_Mask in the Eden pack, and the family resemblance shows: one generates color-coded region animations, this one generates grayscale shape masks. If your goal is a clean binary or shaded mask sweep - like a cinematic reveal where content is masked in as a band moves across - this is the node.
How it works
Under the hood it's a MaskAnimationGenerator that renders each frame's mask at your chosen width/height, then stacks the frames into an IMAGE batch. The modes break into three families:
- moving_band_ - a solid band sweeping across the frame (top-down, bottom-up, left-right, right-left).
- sine_wave_ - a wavy band, with
wave_frequencycontrolling ripple andwave_amplitude_ratiocontrolling wobble, sweeping across in one of four directions. - expanding_circle / contracting_circle - a circle growing from or shrinking to the center.
Two knobs matter more than the rest. num_shades (default 2) sets how many grayscale levels the mask uses - 2 gives hard black/white, which is what you want for feeding a real inpainting mask. Crank it to 16β64 and you get smooth gradient shades instead, which looks great composited but behaves differently when a KSampler treats it as a mask. invert_mask flips which side is active, useful when you want content to leave instead of arrive.
There's also a gradient_type (none / all_edges / trailing_edge) plus gradient_width_ratio that softens mask edges with a distance-based falloff (via OpenCV's distance transform) - all_edges fades every boundary, trailing_edge fades only the moving edge, which gives a lovely blur-sweep reveal effect.
The outputs
- IMAGE - the mask animation,
total_framesframes of widthΓheight. - num_shades, width, height - echoed back as INTs so downstream nodes can use them without guessing.
Wire the IMAGE into a mask-conversion node and then into Set Latent Noise Mask on an inpaint KSampler, and you've got a frame-consistent animated reveal. The KB's inpainting essay is worth a re-read here: masked inpainting still owns bit-identical unmasked pixels, which is exactly the property an animated reveal needs - the already-revealed area stays frozen while only the newly exposed band regenerates.
Installing
It's part of edenartlab/eden_comfy_pipelines (Eden.art nodesuite):
cd ComfyUI/custom_nodes
git clone https://github.com/edenartlab/eden_comfy_pipelines.git
cd eden_comfy_pipelines
pip install -r requirements.txt
Or ComfyUI Manager β search "Eden". It needs opencv-python (in the pack's requirements) for the gradient falloff, but nothing else exotic.
Gotchas
Two real ones. First, the binary-mask trap: the pack prints a warning if you set gradient_type to anything but none while num_shades is 2 - gradients need multiple shades to exist, so you'll get a hard mask and wonder why your soft fade didn't happen. Second, remember the output is IMAGE, not MASK - most inpainting nodes want a MASK, so throw it through a converter (or use it as IMAGE conditioning) before it hits a KSampler. And don't forget the obvious: a total_frames of 64 at 512Γ512 is a chunk of VRAM when it's stacked as a single batch, so keep resolutions sane for long sweeps.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| width | INT | 51224β9223372036854776000 | β |
| height | INT | 51224β9223372036854776000 | β |
| total_frames | INT | 641β9223372036854776000 | β |
| num_shades | INT | 22β256 | β |
| mode | COMBO | 10 options: moving_band_horizontal_td, moving_band_horizontal_bu, moving_band_vertical_lr, moving_band_vertical_rl, sine_wave_vertical_lr, sine_wave_vertical_rl, +4 | |
| invert_mask | BOOLEAN | false | β |
| band_thickness_ratio | FLOAT | 0.200.01β1 | β |
| wave_amplitude_ratio | FLOAT | 0.100β0.5 | β |
| wave_frequency | FLOAT | 2.00.1β20 | β |
| wave_thickness_ratio | FLOAT | 0.050.01β0.5 | β |
| gradient_type | COMBO | none | 3 options: none, all_edges, trailing_edge |
| gradient_width_ratio | FLOAT | 0.000β1 | β |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | β |
| num_shades | INT | β |
| width | INT | β |
| height | INT | β |