Nodes/ComfyUI_SwiftCut/Image Push Pull Lens
ComfyUI Node

Image Push Pull Lens

A Cheap Dolly Zoom, Without the Depth Map

By yichengup·Created about a year ago·Updated 8 months ago· 10
Image Push Pull Lens
  • image
  • frames
  • masks
frames30
start_crop_ratio0.30
middle_crop_ratio0.50
end_crop_ratio0.80
middle_frame15
input_modesingle_to_multi

The dolly zoom - the "Vertigo effect," that unsettling push-in-where-the-background-shifts - is one of those shots people ask about constantly, and the honest answer is that the flashy versions (depthflow, depth-map parallax) are doing real 3D reprojection. Image Push Pull Lens is not that. It's the cheap version: a center crop that grows or shrinks across your frames, resized back to full frame. And for a lot of uses, cheap is exactly right.

This node is the signature move of the SwiftCut pack, and the reason the pack's example workflow exists. Give it a still image and it generates a whole camera move; give it an existing frame sequence and it applies a move to each frame. It's the "motion" in your "image to video with camera movement" recipe that doesn't need a video model at all.

How it works

For each frame it crops a centered rectangle, resizes that crop back up to the original dimensions with Lanczos, and emits both the resulting frames batch and a masks output showing exactly which region survived the crop. The crop size follows a three-stage ramp:

  • start_crop_ratio at frame 0
  • middle_crop_ratio at middle_frame
  • end_crop_ratio at the last frame

Here's the mental model that matters: crop ratio is the fraction of the frame you keep, and a smaller fraction zoomed back up looks bigger. So start_crop_ratio 0.3 → end_crop_ratio 0.8 (the defaults) starts tight and pulls OUT - the classic push-pull reveal. Reverse the numbers and you push IN. Center-based cropping means the subject stays put while the frame seems to breathe around it.

Two modes:

  • single_to_multi - one image becomes frames frames (2–120, default 30), a generated camera move from a still. This is the headline feature.
  • multi_to_multi - takes an existing batch and applies the three-stage crop across it; the frames input is ignored here, your batch length decides.

The honest comparison

If you came here from a "dolly zoom in ComfyUI" search, know what you're getting. depthflow and the depth-based nodes give you true parallax - foreground and background moving at different rates, because they use a depth map. This node gives you a pure scale ramp, which reads as a zoom with extra steps, not a 3D push. But it's also instant, deterministic, and runs on any machine - no depth model, no ControlNet, no VRAM spike. For title cards, logo reveals, and "make my still image feel alive" jobs, the cheap zoom is often the better tool. The masks output is the sleeper feature: wire it into compositing and you can drive a second effect (blur, color grade) off the same crop region the whole way through.

Installing it

Same as every node in this pack:

cd ComfyUI/custom_nodes
git clone https://github.com/yichengup/ComfyUI_SwiftCut

Restart ComfyUI, or use ComfyUI Manager and search "ComfyUI_SwiftCut." It lands under YC_VideoCutHelper → Image. Dependencies are just torch, Pillow, and numpy - no models to download, nothing heavy, which is exactly why the cheap dolly zoom beats the fancy one on a low-spec box.

Where it bites

Two gotchas. First, middle_frame past the batch length gets clamped, and in multi_to_multi the whole frames input is dead weight - set your stage ratios and let the input decide. Second, because everything is a resize of a crop, heavy zoom-ins (ratios below ~0.2) visibly soften the frame. The result is a deliberate "film look" or just mushy, depending on your tolerance. Keep ratios above 0.3 and you'll rarely notice. This pack has basically no reddit footprint, so you won't find a tutorial - but the defaults (30 frames, 0.3→0.8) produce a perfectly usable shot on the first try, which is more than most camera-move nodes can claim.

CategoryYC_VideoCutHelper/Image

Inputs (7)

NameTypeDefaultDescription
imageIMAGE
framesINT302–120
start_crop_ratioFLOAT0.300.1–1
middle_crop_ratioFLOAT0.500.1–1
end_crop_ratioFLOAT0.800.1–1
middle_frameINT151–120
input_modeCOMBOsingle_to_multi2 options: single_to_multi, multi_to_multi

Outputs (2)

NameTypeDescription
framesIMAGE
masksMASK