Drawable Feature Node β‘π ‘π π £π
Hand-key your own curve instead of extracting one
- FEATURE
Every other Feature-source node in this pack extracts a signal from something - audio, color, brightness, depth. This one flips that: you draw the curve yourself. It's the manual-control escape hatch for when you know exactly the shape you want an effect to follow over time and don't want to fake it by fiddling with an audio track or a beat divisor to get there.
How it works
You author a list of [frame, value] control points, and the node interpolates between them to build a full per-frame FEATURE curve spanning frame_count frames. points is technically a JSON string under the hood, but in practice you're meant to set it through the node's own drawable curve widget rather than typing JSON by hand - the field exists as a string because that's how the widget serializes what you draw. interpolation_method decides how the gaps between your control points get filled: linear for straight-line transitions, cubic for smooth curves, nearest to snap to the closest defined point, zero/hold for instant jumps or held values with no smoothing, and ease_in/ease_out for accelerating or decelerating transitions. min_value/max_value remap whatever range you drew into the actual output range you need, and fill_value is what gets used for any frame outside your defined points.
The inputs and outputs that matter
extraction_method- only one real choice here:drawn. Per the tooltip, it "creates a feature from manually specified points - perfect for custom animations."points(default"[]") - "JSON string of [frame, value] pairs"; set this via the curve-drawing widget rather than hand-editing it.frame_count(default 30, range 1β999999) - "Total number of frames."interpolation_method-linear,cubic,nearest,zero,hold,ease_in, orease_out.min_value/max_value(default 0 / 1, range -100 to 100) - the output range your points get mapped into.fill_value(default 0, range -100 to 100) - "Value to use for undefined regions," i.e. frames before your first point or after your last.frame_rate,width,height- standard Feature-source plumbing shared across the pack's source nodes.
Output: a single FEATURE, the hand-authored curve.
How to install it
Via ComfyUI Manager: search "RyanOnTheInside," install, restart. By hand:
cd ComfyUI/custom_nodes
git clone https://github.com/ryanontheinside/ComfyUI_RyanOnTheInside.git
cd ComfyUI_RyanOnTheInside
pip install -r requirements.txt
then restart. Nothing external to fetch - this is entirely local UI and interpolation math.
Common issues & troubleshooting
Curve looks jagged when you expected it smooth. Check interpolation_method - linear gives you straight segments between points, which can look angular with few control points; switch to cubic for a smoother result, or add more points along the way you want the curve to follow.
Values outside your drawn range don't behave as expected. That's fill_value - anything before your first keyframe or after your last one uses that flat value, not an extrapolation of the trend. If your effect looks like it "resets" unexpectedly at the edges, this is why.
The feature's actual output range doesn't match what you drew. Remember min_value/max_value remap your drawn points into that range - if you drew a curve from 0 to 1 visually but set max_value to 100, the actual output will scale up accordingly. Match these to whatever range the downstream node you're driving actually expects.
Points don't line up with your video length. frame_count has to match (or be intentionally different from) the length of whatever else you're driving - a mismatch here means your carefully drawn curve gets stretched, truncated, or padded with fill_value in ways you didn't intend.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| extraction_method | COMBO | Choose how to analyze drawn points: - drawn: Creates a feature from manually specified points - perfect for custom animations | |
| frame_rate | FLOAT | 30.01β120 | Frame rate of the video (1.0 to 120.0 fps) |
| frame_count | INT | 301β999999 | Total number of frames (minimum: 1) |
| width | INT | 51264β4096 | Width of the output feature (64 to 4096) |
| height | INT | 51264β4096 | Height of the output feature (64 to 4096) |
| points | STRING | [] | JSON string of [frame, value] pairs |
| min_value | FLOAT | 0.0-100β100 | Minimum value for the feature (-100.0 to 100.0) |
| max_value | FLOAT | 1.0-100β100 | Maximum value for the feature (-100.0 to 100.0) |
| interpolation_method | COMBO | linear | Method for interpolating between points: - linear: Smooth straight-line transitions - cubic: Smooth curved transitions - nearest: Snap to closest point - zero: No interpolation, instant changes - hold: Keep previous value until next point - ease_in: Gradually accelerate changes - ease_out: Gradually decelerate changes |
| fill_value | FLOAT | 0.0-100β100 | Value to use for undefined regions (-100.0 to 100.0) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| FEATURE | FEATURE | β |