Skip to content

Studio: re-expose keyframe retiming via a UI gesture (reducer already supports it, just unwired since #1763) #1782

Description

@nicolasfilippini

Summary

Since #1763 removed the timeline keyframe-drag affordance, there is no GUI gesture left to retime an existing keyframe in time while preserving its value and easing. The only ways to move a keyframe in time via the UI now (delete + re-add at playhead, toggle-at-playhead) bake the current computed values and drop the explicit ease — so the author loses the keyframe they were trying to move.

The interesting part: the capability to retime-while-preserving still exists in the reducer — it's just not wired to any UI action anymore.

What still exists vs. what's reachable

Reading the served Studio bundle (dist/studio/assets/index-*.js, v0.7.18), the reducer handles a setGsapKeyframe action that does exactly the right thing:

case "setGsapKeyframe":
  return nAe(t, e.animationId, e.keyframeIndex, e.position, e.value, e.ease);
// nAe: position = e.position ?? current ; value = e.value ?? {...existing.properties} ; ease = e.ease ?? existing.ease
//  → passing ONLY a new `position` retimes the keyframe while keeping its value AND ease.

But setGsapKeyframe appears only twice in the whole bundle — the reducer case above and the validation switch. No UI code dispatches { type: "setGsapKeyframe", position: … }. The keyframe diamond now binds only onClick (select + seek) and onContextMenu, and the context menu wires only "change ease" and "delete" — there is no "set time / move to playhead" action. So the preserving-retime path is reachable from the SDK/code but dead from the GUI.

Request

Re-expose keyframe retiming through a UI gesture by dispatching the existing setGsapKeyframe with a new position (preserving value + ease). A drag affordance isn't required — a menu entry is enough. For example, add to the keyframe context menu:

  • "Move keyframe to playhead"setGsapKeyframe({ animationId, keyframeIndex, position: playheadPercent }), and/or
  • an editable time / percentage field for the selected keyframe.

This reuses code that's already present; it's a wiring task, not new engine work.

Use case / motivation

Our workflow has a non-technical author posing keyframes by gesture in the Studio, then a technical editor refining in source. Retiming is currently the one operation that can't be done at the gesture level without destroying the keyframe — so every retime has to round-trip through hand-editing tl.to(sel, { keyframes: { … } }) in code. Restoring a gesture that retimes-in-place (preserving value + ease) would let the author iterate on timing directly, which is the common case.

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions