Trajectory ▸ Drawer
Draw glowing motion trails on any image and export them as an animated sequence
- base_image
- frames
- info
- tracks_json
TrajectoryDrawer is the one node in the ComfyUI-WanMove-Trajectory pack, and despite the "Wan Move" in the repo name, it's not a video model at all. It's a tiny motion-graphics generator: you draw a path on top of any single image, and it renders an animation of a glowing dot tracing that path with a light trail behind it. Out come a full batch of frames ready for SaveImage or VideoHelperSuite, plus the coordinates as JSON.
Why would you want that? The author's framing is Wan Move - a reference animation showing exactly where motion happens, which you can feed into a motion-transfer workflow as a guide. But the honest use is broader: annotated path overlays for tutorials, neon-sign-style text, presentation pointers, debugging where a ControlNet or video model actually moved. There's no AI in here. No model download, no sampler, no API key, no VRAM. Just PIL, NumPy, and a canvas you draw on with your mouse.
How it works
The node reads three things: your image, a path_json trajectory, and a pile of style knobs. The trajectory is the interesting part. Instead of typing coordinates, you open the built-in editor - click Edit Trajectory (Shift Draw) on the node and a canvas overlay appears. You can load any PNG/JPG as a reference (the canvas adopts its resolution), then hold Shift and drag to draw strokes. Apply Path writes the JSON back into the path_json input, and because it lives in the workflow JSON, you can version, reuse, and share trajectories without touching any files.
At runtime the draw() function takes that JSON, interpolates between your drawn points (frames_per_segment controls how densely), resamples the stroke to fit the target duration, and composites one RGBA overlay per frame: a circular head, a fading gradient tail, and an optional pointer arrow. trail_decay is the tail's memory - the lower the value, the longer the trail persists. Pure PIL drawing, tens of frames a second, no GPU needed.
The inputs that matter
You'll set most of these once and leave them alone. The ones you actually touch:
path_json- the required trajectory. Leave it empty and the node will tell you there's nothing to draw; open the canvas and make one.stroke_width(1–200) andline_color- the look. Color takes hex (#00f0ffis the default neon cyan) orr,g,b.trail_decay(0–1) andbackground_dim(0–1) - trail length, and how much to darken the base image so the glow pops.background_dimaround 0.2–0.4 gets you close to the reference-video aesthetic.duration_secondsandfps- setduration_secondsto 0 to derive the length from the stroke; otherwise it's target duration. Keepfpsthe same downstream when you assemble the video.
Also available: frames_per_segment, tail_alpha, line_style (solid or neon), and show_pointer (a debug arrow that doesn't touch the glow).
Outputs
frames- theIMAGEbatch, the whole animation. Pipe it intoSaveImagefor a PNG sequence orVideoHelperSuite ▸ ImagesToVideofor an MP4/GIF.info- aSTRINGof JSON metadata (frame count, resolution, fps, decay settings).tracks_json- aSTRINGlisting every pixel coordinate per stroke, if you want to feed the path into a script or another node.
Installation
Install via ComfyUI Manager (search "WanMove-Trajectory") or the manual way:
cd ComfyUI/custom_nodes
git clone https://github.com/starsFriday/ComfyUI-WanMove-Trajectory
Then restart ComfyUI - the node appears under the 🧭 Trajectory category. There are no dependencies beyond what ComfyUI already ships, so no pip installs and no model downloads. The README's install line mentions a ComfyUI-Trajectory folder, which is a stale copy-paste; clone the repo under its actual name and you're fine.
Where people get burned
- Only the first frame of
base_imageis used. Feed it a batch and the rest is silently ignored - split batches upstream if you need several trajectories. - Desktop needs
Shift. The canvas draws on touch devices directly, but on a desktop holdingShiftis required; otherwise you just get a reminder. - The JSON embeds the reference image as Base64, not a file path. Keep the original file around; don't rely on the workflow to hold it forever.
duration_seconds = 0derives length from stroke length, so a tiny scribble can turn into a very short clip - set a fixed duration if your pacing looks frantic.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| base_image | IMAGE | — | |
| path_json | STRING | — | |
| stroke_width | FLOAT | 30.01–200 | — |
| frames_per_segment | INT | 41–32 | — |
| line_color | STRING | #00f0ff | — |
| tail_alpha | FLOAT | 1.000.1–1 | — |
| background_dim | FLOAT | 0.000–1 | — |
| trail_decay | FLOAT | 0.300–1 | — |
| line_style | COMBO | 2 options: solid, neon | |
| fps | INT | 301–120 | — |
| duration_seconds | FLOAT | 5.00–120 | — |
| show_pointer | COMBO | 2 options: disable, enable |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| frames | IMAGE | — |
| info | STRING | — |
| tracks_json | STRING | — |