Batch2d Transform (mtb)
Keyframed pan, zoom and rotate on an image batch
- image
- constant_color
- x
- y
- zoom
- angle
- shear
- IMAGE
This is the workhorse of MTB's animation toolkit. Batch2d Transform applies a 2D move - translate, zoom, rotate, shear - to a batch of images, where each transform value is animated by a curve. Feed it a per-frame zoom curve and it does a smooth Ken Burns push-in. Feed it a rotation curve and it spins. It's the same idea as Deforum's 2D motion, done as a Comfy node.
The key concept is that the transform parameters aren't single numbers - they're FLOATS, lists with one value per frame. Frame 0 uses the first value, frame 1 the second, and so on. So the animation lives in the curves you build (with the other batch-float nodes in this pack), and this node just applies them.
How it works
For each image in the batch, it reads the matching entry from each curve and applies an affine transform: shift by x/y, scale by zoom, rotate by angle, skew by shear. Whatever region gets exposed at the edges when you move or zoom out is filled according to border_handling. The result is a transformed batch you render out as video.
The inputs and outputs that matter
image(IMAGE) - the batch to transform. A single image works too, but the point is a batch.x/y/zoom/angle/shear(all optional FLOATS) - the animation curves. Wire in the ones you want to move; leave the rest unconnected to hold them steady.use_normalized(optional, default false) - whetherx/yare treated as normalized (0–1 of the frame) or raw pixels. Decide this based on how you built the curve.border_handling-edge(repeat the border pixels),constant(fill withconstant_color),reflect, orsymmetric.constant_color(COLOR) - the fill color whenborder_handlingisconstant.
Output is a single IMAGE batch → your video combine / save node.
How to install it
Via ComfyUI Manager: search MTB Nodes, install, restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/melMass/comfy_mtb
then restart. No models.
Common issues & troubleshooting
The motion is jerky or stops partway. Your curve length should match your batch length. If you've got 100 frames but a 50-value zoom curve, the back half won't animate the way you expect. Build the curve to the same length (Batch Float Fill and Assemble in this pack are for exactly this).
Zooming out shows a weird repeated border. That's border_handling on edge smearing the edge pixels. Switch to constant with a color you want, or reflect/symmetric for a mirrored fill that usually reads better than edge-smear.
My x/y values do nothing / do way too much. That's the normalized-vs-pixels mismatch. A value of 0.5 means half the frame under normalized mode and half a pixel under pixel mode. Set use_normalized to match how you authored the numbers.
Where do the curves come from? The other batch-float nodes: build a base curve, remap it with Batch Float Fit (which adds easing), pad it with Batch Float Fill, stitch segments with Batch Float Assemble. This node is the last step that turns curves into motion.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| border_handling | COMBO | edge | 4 options: edge, constant, reflect, symmetric |
| constant_color | COLOR | #000000 | — |
| xopt | FLOATS | — | |
| yopt | FLOATS | — | |
| zoomopt | FLOATS | — | |
| angleopt | FLOATS | — | |
| shearopt | FLOATS | — | |
| use_normalizedopt | BOOLEAN | false | If true, transform values will be scaled to image dimensions. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |