@remotion/studio: Interpret keyframes as runtime values with drag overrides - #7802
Conversation
…rrides Closes #7779 - Add interpolateKeyframedStatus() to compute the value of a keyframed prop at the current frame. - In wrapInSchema, override keyframed props with the dynamically calculated value instead of falling back to the runtime value. - In the Timeline, show the calculated value (gray, non-editable) instead of a static 'keyframed' label. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…runtime-overrides
@remotion/studio: Interpret keyframes as runtime values with drag overrides
…runtime-overrides # Conflicts: # packages/studio/src/components/Timeline/TimelineEffectFieldRow.tsx
There was a problem hiding this comment.
Reviewed changes — Adds interpolateKeyframedStatus() to compute interpolated values for keyframed props at the current frame, wires it through wrapInSchema so components receive dynamically calculated values, and updates the Timeline to display the computed value (grayed out, non-interactive) instead of a static "keyframed" label.
- Add
interpolateKeyframedStatus()utility — Runsinterpolate()/interpolateColors()using parsed keyframe metadata (easing, clamping) from the AST. Returnsnullon error or unsupported type mixtures. - Update
computeEffectiveSchemaValuesDotNotation— Accepts aframeparameter; for keyframed props, returns the interpolated value instead of the raw runtime fallback. - Wire
useCurrentFrame()inwrapInSchema— Forwards the current frame so the wrapped component receives the dynamically calculated keyframed value. - Add
TimelineKeyframedValuecomponent — Displays the interpolated value using the same field renderer as editable props, but grayed out and non-interactive. - Plumb
keyframeDisplayOffset— Passed through the Timeline component tree so displayed values account for parent sequence offsets.
✅ No new issues found.
Clean, focused change. The try/catch around interpolate() and interpolateColors() provides a safe fallback if parser-produced easing arrays ever have unexpected lengths. The frame: null path in getFieldsToShow correctly preserves the existing behavior for schema discovery while wrapInSchema gets the animated value.
Kimi K2 | 𝕏
There was a problem hiding this comment.
Reviewed changes — Incremental review of commits pushed since the prior review (2eddc95 and 6267ccc).
2eddc95— Limit interpolated value display to 2 decimals —TimelineKeyframedValue.tsxnow rounds numeric interpolated values to 2 decimal places before rendering. Clean UX improvement that prevents long floating-point noise in the Timeline field row.6267ccc— Merge fromorigin/main— Conflict resolution inTimelineEffectFieldRow.tsxcorrectly preserves both the new keyframed-value rendering from this PR and the reset/context-menu functionality that landed onmain. The rename ofTimelineFieldRow→TimelineSequenceFieldRowinTimelineExpandedRow.tsxis also correctly reflected.
✅ No new issues found in the incremental changes. Merge conflict resolution is clean and the decimal rounding is a nice polish touch.
Kimi K2 | 𝕏

Closes #7779
Previously, when Studio's Visual Mode encountered a prop wired up with
interpolate()orinterpolateColors(), it treated the prop status as non-editable and fell back to the runtime value evaluated by the user's JSX expression. Keyframes were detected and surfaced as keyframe markers on the timeline, but the parsed easing/clamping/keyframe metadata were otherwise unused at render time.This PR interprets the parsed keyframes properly:
interpolateKeyframedStatus({frame, status})utility in@remotion/corerunsinterpolate()/interpolateColors()using the keyframes, easing, and clamping captured from the AST.computeEffectiveSchemaValuesDotNotationnow accepts aframeand, for keyframed props, returns the interpolated value instead of the runtime fallback.wrapInSchemareadsuseCurrentFrame()and forwards it so that the wrapped component receives the dynamically calculated value (the foundation for later allowing edits at specific frames).The
keyframeDisplayOffsetalready used for visual keyframe lanes is plumbed down so the displayed value matches the frame the JSX expression evaluates at (i.e. global playhead minus parent sequence offset).