Skip to content

feat(studio): runtime-synced design panel + 3D props + split polish#1188

Open
miguel-heygen wants to merge 9 commits into
feat/keyframes-7-fixes-polishfrom
feat/keyframe-property-inspector
Open

feat(studio): runtime-synced design panel + 3D props + split polish#1188
miguel-heygen wants to merge 9 commits into
feat/keyframes-7-fixes-polishfrom
feat/keyframe-property-inspector

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

Summary

  • Design panel Layout fields (X, Y, W, H, R) read GSAP-interpolated values from gsap.getProperty() at the current seek time — values update live when scrubbing
  • 3D transform properties added to SUPPORTED_PROPS: z, rotationX, rotationY, rotationZ, perspective, transformOrigin
  • Stronger clip selection border (full accent, glow shadow) and wider keyframe diamond tolerance (0.5% vs 0.05%)
  • DOM selection syncs to timeline selectedElementId on cold-load URL restore
  • Split restricted to media elements only (video/audio/img) — hidden for divs and compositions
  • Phosphor Scissors icon replaces inline SVG

Stacked on #1172.

…rties

The Layout section (X, Y, W, H, R) now reads GSAP-interpolated values
from the runtime via gsap.getProperty() at the current seek time. When
an element has GSAP animations, the fields reflect the actual interpolated
position/size/rotation instead of the CSS defaults.

Also adds 3D transform properties to SUPPORTED_PROPS: z, rotationX,
rotationY, rotationZ, perspective, transformOrigin.
… tolerance

- Selected clip: full accent border (was 38% opacity), subtle glow shadow
- Keyframe diamond at playhead: tolerance 0.5% (was 0.05% — too tight at
  high zoom levels, causing diamonds to never highlight)
Extract useAnimatedPropertyCommit hook that handles the three-case commit
logic: keyframed → add-keyframe, flat → convert + add, no animation →
create + convert + add. Wire Z, Scale, RotX, RotY design panel fields
and 2D Layout fields through this unified pipeline.

Export readAllAnimatedProperties and readGsapProperty from the runtime
bridge so the commit helper can read all animated props for backfill.
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-7-fixes-polish branch from 1937dd3 to c048e70 Compare June 5, 2026 03:22
@miguel-heygen miguel-heygen force-pushed the feat/keyframe-property-inspector branch from ec0c763 to 69354c0 Compare June 5, 2026 03:22
These design plans were accidentally committed and should not be in
the PR.
Copy link
Copy Markdown
Collaborator

@jrusso1020 jrusso1020 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Top-of-stack polish + 3D props. +362/-58. The 3D property additions are the most interesting cross-stack change — they extend the keyframeable surface from 2D transforms into 3D space.

3D transform properties — z, rotationX/Y/Z, perspective, transformOrigin

Two cross-browser concerns:

1. perspective placement matters

perspective set on an element creates 3D context for its children, not itself. If a user sets perspective: 800 on an element and expects that element's own 3D rotation to depth-render, they'll see a flat result. The Studio UI should either:

  • Auto-apply perspective to the parent when a 3D property is set on a child.
  • OR document the rule clearly in the property-panel UI (e.g., "set perspective on the parent of this element").

Without one of these, users will silently get flat-looking 3D and not understand why.

2. transformOrigin interaction with GSAP xPercent / yPercent

GSAP's xPercent: -50 / yPercent: -50 (centering pattern) interacts with transformOrigin. If the SUPPORTED_PROPS set now includes both transformOrigin and the existing transform props, verify the property panel doesn't allow conflicting combinations (e.g., setting xPercent: -50 and transformOrigin: "top left" simultaneously without a warning).

gsap.getProperty() at current seek time — design panel sync

Reading interpolated values from the live runtime is the right approach. Two questions:

  • Cost: getProperty() is cheap for a single element but called for every visible field on every scrub. With Layout (5 fields × multiple selected clips), this could be 20+ calls per scrub frame. Worth a memo with the scrub time as the dep so it batches per-frame.
  • Stale during transition: between seek() and the next runtime sync, getProperty() returns pre-seek values. Verify the design panel reads happen after the runtime has applied the seek (likely via the runtime bridge from #1169's optimistic-update pipeline).

Clip selection border (full accent + glow shadow) + 0.5% diamond tolerance

Both are UX-polish tunings. The 0.5% diamond tolerance (vs the prior 0.05%) is a 10× widening — confirm this matches user-tested expectations and doesn't make adjacent diamonds in dense timelines confusable.

DOM selection syncs to timeline selectedElementId on cold-load URL restore

Important for shareable Studio URLs. Verify the sync handles the case where selectedElementId references a stale element (no longer in the DOM after a script edit). Silent no-select or fallback to first element is fine; uncaught error is not.

Phosphor Scissors icon — duplicates #1189

Both #1189 and this PR mention the Phosphor Scissors icon. Once the stack merges in order, the second one is a no-op. Just flagging that the icon import lives in two PRs of the same stack.

Review by Jerrai (hyperframes specialist)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants