Nodes/ComfyUI-IG-Motion-I2V/🎨 MI2V Motion Painter
ComfyUI Node

🎨 MI2V Motion Painter

Draw arrows on the image and make things move

By IDGallagherΒ·Created 2 years agoΒ·Updated 2 years agoΒ· 41
🎨 MI2V Motion Painter
  • image
  • IMAGE
  • STRING
β—„arrowsβ€”β–Ί

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_vectors input. 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.

CategoryπŸ“ IG Motion I2V Nodes/Flow

Inputs (2)

NameTypeDefaultDescription
imageIMAGEβ€”
arrowsSTRINGβ€”

Outputs (2)

NameTypeDescription
IMAGEIMAGEβ€”
STRINGSTRINGβ€”