Apply Curve to Conditioning
The node that makes per-frame prompt emphasis real
- curve
- cond
- latents
- CONDITIONING
Here's where curves stop being abstract and start moving pixels. Apply Curve to Conditioning takes a curve and a conditioning, and produces a batch of conditionings where each entry is the conditioning multiplied by the curve's value at that entry's index. If a curve is 0.8 at frame 10 and 0.2 at frame 20, frame 10's conditioning gets weighted at 0.8 and frame 20's at 0.2. That's per-frame prompt strength, and it's the mechanism behind a huge amount of AnimateDiff-era prompt scheduling.
The classic use: you've evaluated a prompt schedule into a batch of conditionings (one per frame), and you want a particular prompt's influence to fade across the clip. Curve it, multiply, done. Combined with the pack's Add Conditions nodes, this is also how you build the "prompt superposition" effect where several prompts contribute simultaneously, each weighted by its own curve. The README's manual prompt-transition workflow is exactly this: separate weight curves per prompt, applied to each prompt's conditioning, all summed to one.
How it works
For each conditioning entry in the batch, the node reads the curve at start_t + index and multiplies the conditioning tensor by that weight (the pooled output gets the same treatment, which matters because SD-style models read both). The size of the batch is decided in priority order: if your cond input already has batch size greater than 1, that wins; otherwise the batch comes from the optional latents input's batch dimension; otherwise the n input decides. That tri-level rule is the one thing to memorize about this node - it's how it stays flexible whether you're feeding raw schedule output, a latent batch, or a hand-set count.
The inputs that matter
curve(required) - the weight curve. Usually in the 0–1 range; that's what makes it a "weight."cond(required) - the conditioning to batch and scale.latents(optional) - provide a LATENT and its batch size sets the output count.start_t(optional) - which time index the first entry samples the curve at (default 0).n(optional) - batch size, used only if neithercondnorlatentspins it.
The output
CONDITIONING - a batch-sized conditioning ready for a sampler that consumes per-frame conditioning, like AnimateDiff's.
How to install it
Standard pack install: ComfyUI Manager → search ComfyUI-Keyframed, or
cd ComfyUI/custom_nodes
git clone https://github.com/dmarx/ComfyUI-Keyframed
then restart ComfyUI. No models to download - the only dependency is the keyframed library (plus toolz), auto-installed on first import.
Troubleshooting
The priority rule is where people get burned: if your cond came from a schedule evaluated as a single conditioning, its batch is 1, and the node will happily broadcast to n - but if it came pre-batched, n is silently ignored. If your weights aren't landing where you expect, check which of the three size sources is actually winning. Also, curve values outside 0–1 are legal and produce over- or under-emphasis rather than errors, which is useful for drama and bad for debugging. Plot the curve first (KfCurveDraw is right there) before you trust the output.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| curve | KEYFRAMED_CURVE | — | |
| cond | CONDITIONING | — | |
| latentsopt | LATENT | — | |
| start_topt | INT | 0 | — |
| nopt | INT | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| CONDITIONING | CONDITIONING | — |