π¨ MI2V Motion Painter
Draw arrows on the image and make things move
- image
- IMAGE
- STRING
The MI2V Motion Painter is where this pack stops being "another I2V wrapper" and becomes something you haven't seen anywhere else. Instead of describing motion with words, you literally draw it: drag on the image to place an arrow, and that arrow tells the video which direction that part of the scene should travel. Left-drag places an arrow, right-click removes one - the node's own description, and honestly the whole tutorial you need.
This is the interaction layer for the MI2V Flow Predictor. The arrows you draw get serialized into motion vectors, and the predictor turns them into the optical flow that the Flow Animator renders. The painter itself does no generation at all - it's a vector-input tool with a canvas attached.
How it works
The node is a browser-side canvas (the code is adapted from AlekPet's painter node, per the README credits). When you run the workflow, the node pushes your image to the canvas over a websocket and waits for you to interact - it literally holds execution waiting for a canvas change. Each arrow becomes a line of four numbers, x1,y1,x2,y2 (start point, end point), stored in the node's arrows string field. That string is the node's memory: it survives graph saves and re-runs, so your drawn motion doesn't evaporate when you reload the workflow.
Two inputs, both required:
- image (IMAGE) - the frame you're animating. It renders as your drawing surface.
- arrows (STRING) - the serialized arrow data. You usually don't type here; the canvas writes it.
Two outputs:
- IMAGE - your image, passed through untouched.
- STRING - the arrow list. Wire this into the Predictor's
motion_vectorsinput. This is the important one.
The size trap (read this before you draw)
Arrows are stored in pixel coordinates and scaled by the Predictor to whatever size it runs at. So the canvas image and the predictor's input image must be the same dimensions, and since the Predictor silently resizes to the nearest multiple of 8, you want your image pre-sized - 1024Γ576, 1024Γ1024, whatever, just make it a clean multiple of 8 before you touch the canvas. The README's workflow handles this with the MI2V Pause node: pause, load the correctly-sized image, draw your arrows, unpause. Draw first and resize after, and every arrow lands somewhere wrong.
Reading your own arrows
Direction is displacement: an arrow pointing down moves that region down over the 16 frames. Length is speed - a long arrow is a big travel, a short one a nudge. Keep arrows on the region you actually want to move and let the prompt fill in the rest. And a fun detail from the code: a lone point (no drag) becomes a stationary tracking point - it pins that location in place. Useful for holding a subject still while the background moves.
Install
Same pack as the rest of the IG Motion I2V nodes - ComfyUI Manager (search "IG Motion I2V") or:
cd ComfyUI/custom_nodes
git clone https://github.com/IDGallagher/ComfyUI-IG-Motion-I2V
# restart ComfyUI
The painter needs no models and no extra deps of its own - the canvas is pure front-end (fabric.js ships in the pack's web/ folder). The heavy dependencies (diffusers, cupy-cuda12x, omegaconf, xformers, and the ~17.3GB checkpoint) belong to the predictor and animator you're feeding.
Gotchas
If the canvas never appears or arrows don't stick, restart ComfyUI after installing - the node mounts its web assets at load time and a stale session won't pick them up. And one more honest note: this is 2024-era explicit motion control, and it's genuinely fun and unique - but it's also the fiddliest part of an already-fiddly pack. Budget some patience for the size alignment, because that single detail is where most people's arrow-drawing sessions go sideways.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | β | |
| arrows | STRING | β |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | β |
| STRING | STRING | β |