π Frame Maker
Pan and zoom a subject into animation keyframes β no model, no API
- subject_image
- subject_alpha
- bg1
- bg2
- bg3
- bg4
- frames
- frames
- subject_image
- width
- height
- frame_count
The name makes it sound like it renders frames. It doesn't. FrameMaker is a compositor: it takes one subject image, pastes it over a background, and moves and scales it across frame_count steps to emit a batch of keyframes. No diffusion model involved, no weights to download, no API key, nothing running on your GPU - just PIL doing pan/zoom math while your VRAM sits idle.
It exists because animation in ComfyUI needs starting points. You can't get coherent motion from a single still, and hand-placing a character frame by frame is misery. FrameMaker generates the keyframes instead: you get a clean camera move (or subject move) on a transparent or cut-out subject, then hand those frames to something that adds motion - AnimateDiff with SparseCtrl, LayerDiffusion, or a frame-interpolator like RIFE VFI before VHS_VideoCombine turns the batch into a clip. That's exactly the pipeline diSty (diStyR on Reddit) built it for - his "splash" guided-motion workflow - and it's the shape to keep in your head when you wire this up.
How it works
Mechanically it's simple and old-school: your subject_image is converted to PIL, optionally joined with subject_alpha into an RGBA matte, and pasted onto a background at a position that linearly interpolates from x_pos_start/y_pos_start to x_pos_end/y_pos_end across frame_count frames. Scale does the same from scale_start to scale_end. That's the whole trick.
Two things quietly override your manual values, and both are in the source:
movement_presets(25 of them, "left to center", "center to right", diagonals, the lot) replacex_pos_start/endandy_pos_start/endwhen it isn'tNone.movement_presets_distanceis a percentage of the image dimensions, default 50 - so on a 768px canvas that's 384px of travel.movement_directionreplaces your scale values outright:frontsets scale 0.3 β 1.3 (subject grows toward camera),backsets 1.3 β 0.3. Set it toNoneif you wantscale_start/scale_endto actually mean something.
scale_anchor_point (center, corners, top/bottom center) controls where the scaling pivots, and the optional bg1βbg4 backgrounds cycle frame by frame - handy for a multi-shot clip. Connect the frames input and it ignores the backgrounds entirely, using those frames instead. invert_order flips the output batch, which is a free reverse-play.
The inputs that matter
A beginner really sets about four things, everything else defaults sensibly:
- subject_image - your character/object, ideally already cut out.
- frame_count - 4 is the default and it's a good keyframe count; you'll interpolate up later.
- movement_presets + movement_presets_distance - the easiest way to get a clean pan.
- invert_alpha - flips the alpha matte; if your subject renders as a see-through ghost or a block, flip it.
Outputs are the money shot: frames (the IMAGE batch - wire it into your sampler, VFI, or video combine), plus subject_image, width, height, and frame_count ints for downstream sizing.
Install
The pack ships no requirements.txt and downloads no models - this is the rare custom node that's genuinely light.
cd ComfyUI/custom_nodes
git clone https://github.com/diStyApps/ComfyUI_FrameMaker
# restart ComfyUI
Or just use ComfyUI Manager and search "Frame Maker" - that's the recommended path in the README, and Manager will keep it updated.
Troubleshooting
frame_countof 1 crashes - the interpolation divides byframe_count - 1, so a single frame is a divide-by-zero. Keep it at 2 or more.- Your scale values get ignored -
movement_directionis set tofrontorback. Set it toNone. - Your x/y positions get ignored - a movement preset is overriding them. Set
movement_presetstoNone. - Subject looks like a hole - flip
invert_alpha. - Output is 768Γ768 no matter what you loaded -
resize_frame_inputdefaults totrueand forces everything toframe_input_width/frame_input_height(768). If you want your real resolution, either change those or setresize_frame_inputtofalseand keep subject and background the same size so the paste math lines up.
Inputs (26)
| Name | Type | Default | Description |
|---|---|---|---|
| subject_image | IMAGE | β | |
| frame_count | INT | 4 | β |
| invert_alpha | COMBO | false | 2 options: true, false |
| movement_presets | COMBO | left to center | 25 options: None, left to center, right to center, center to left, center to right, left to right, +19 |
| movement_presets_distance | INT | 50-10000β10000 | β |
| movement_direction | COMBO | back | 3 options: None, front, back |
| x_pos_start | INT | 0-10000β10000 | β |
| x_pos_end | INT | 0-10000β10000 | β |
| y_pos_start | INT | 0-10000β10000 | β |
| y_pos_end | INT | 0-10000β10000 | β |
| scale_start | FLOAT | 1.000.05β10 | β |
| scale_end | FLOAT | 1.000.05β10 | β |
| scale_anchor_point | COMBO | 7 options: center, top center, bottom center, top left, top right, bottom left, +1 | |
| subject_alphaopt | MASK | β | |
| bg1opt | IMAGE | β | |
| bg2opt | IMAGE | β | |
| bg3opt | IMAGE | β | |
| bg4opt | IMAGE | β | |
| framesopt | IMAGE | β | |
| resize_frame_inputopt | COMBO | true | 2 options: true, false |
| frame_input_widthopt | INT | 76816β8192 | β |
| frame_input_heightopt | INT | 76816β8192 | β |
| resize_frame_outputopt | COMBO | false | 2 options: true, false |
| frame_output_widthopt | INT | 51216β8192 | β |
| frame_output_heightopt | INT | 51216β8192 | β |
| invert_orderopt | COMBO | false | 2 options: true, false |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| frames | IMAGE | β |
| subject_image | IMAGE | β |
| width | INT | β |
| height | INT | β |
| frame_count | INT | β |