Files
Miguel Ángel 7e0711505a fix(studio): hide handles Studio would refuse to commit (#4666)
* fix(studio): hide handles Studio would refuse to commit

Studio showed move, resize and rotate handles on animated elements whose
motion it cannot write back (a helper or loop, a runtime-computed value, a
live tween with no matching source). The drag ran, the commit was refused
at release, the element snapped back and a toast explained why.

The commit's refusal rules now also run when a selection resolves:
- move uses the existing drag preflight, now exported
- rotation and resize rules are extracted into preflight functions that the
  commit paths call first, so both use the same decision code
- the session narrows canApplyManualOffset / Size / Rotation (with the
  refusal's message as reasonIfDisabled) in one place, and the chrome,
  nudge, group drag and design panel read that unchanged
- until an element's first check lands, its manual flags stay closed

A press on a box that cannot move now shows the reason at once instead of
after 4px of travel.

* refactor(studio): read the rotation preflight selector once and derive the scale flag

* fix(studio): make the handle check read what the commit reads, and never stall

- Match tweens to an element the same way everywhere: the animation fetch
  used by the handle check and by group moves now also matches through the
  live element, so an element a class tween animates keeps its handles.
- The handle check reads each file's parse once per edit version. A file with
  no tweens is an answer, not a cold parse to retry, so plain elements get
  their handles after one read and later selections in that file at once.
- A failed read is not remembered: the next selection asks again.
- While the check is still running a press stays silent, and only the primary
  button explains a blocked press. A group press with a blocked member now
  says why instead of doing nothing.

* fix(studio): check handles per project, keep answers on failed reads, refuse shared group tweens

- The handle check's parse cache now uses the same project and file key as
  the parse request, so switching projects never judges one project's file
  by another's parse.
- A failed re-read after a save or undo keeps the last good answer and asks
  again on the next selection, instead of closing the handles.
- A group move stays refused when a member's motion comes from one tween
  shared with other targets, as before: each member would write into the
  same tween. The group check and the group commit use the same rule; a
  single selection still edits the shared tween.
- The element-to-tween matcher moves to its own module so the move rule can
  use it without an import cycle.

* docs(studio): the group move rule comment says which tweens it excludes
2026-09-28 23:48:01 +00:00
..
2026-09-28 13:37:47 -07:00

@hyperframes/studio

Browser-based composition editor UI for Hyperframes. Provides a visual timeline, code editor, and live preview for building video compositions.

Install

npm install @hyperframes/studio

What it does

The studio is a React application with:

  • Visual timeline — drag, resize, and arrange elements on tracks
  • Code editor — edit HTML and GSAP scripts with CodeMirror (syntax highlighting, autocomplete)
  • Live preview — see changes in real time as you edit
  • Composition inspector — view and modify element properties

Development

The studio is embedded in the hyperframes preview command. To develop the studio UI itself:

cd packages/studio
bun run dev        # Start Vite dev server
bun run build      # Build for production
bun run typecheck  # Type-check

Tech stack

  • React 19, Zustand 4/5 (state management; development uses Zustand 5)
  • CodeMirror 6 (editor)
  • Tailwind CSS (styling)
  • Vite (bundler)
  • Phosphor Icons

Documentation

Full documentation: hyperframes.heygen.com/packages/studio