Skip to content

feat(studio): split clip at playhead for media elements [7/10]#1189

Open
miguel-heygen wants to merge 1 commit into
feat/keyframes-4b-design-panel-polishfrom
feat/keyframes-5-split-clip
Open

feat(studio): split clip at playhead for media elements [7/10]#1189
miguel-heygen wants to merge 1 commit into
feat/keyframes-4b-design-panel-polishfrom
feat/keyframes-5-split-clip

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

Summary

  • Add splitElementInHtml to core source mutation — clones element, adjusts timing/media-start
  • split-element API endpoint
  • handleTimelineElementSplit handler with media-only guard
  • Clip context menu: right-click → Split at Xs
  • S keyboard shortcut
  • Toolbar split button (Phosphor Scissors icon)

+245 LOC

@miguel-heygen miguel-heygen force-pushed the feat/keyframes-4b-design-panel-polish branch from 9a94cd9 to bc87ce5 Compare June 4, 2026 04:57
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-5-split-clip branch 2 times, most recently from 0dbfe93 to 925397e Compare June 4, 2026 16:15
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-4b-design-panel-polish branch from bc87ce5 to 55d81f3 Compare June 4, 2026 16:15
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-5-split-clip branch from 925397e to 4711c17 Compare June 4, 2026 16:40
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-4b-design-panel-polish branch 2 times, most recently from 1670e95 to 6f66981 Compare June 4, 2026 17:44
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-5-split-clip branch from 4711c17 to 32dd0bb Compare June 4, 2026 17:44
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-4b-design-panel-polish branch from 6f66981 to 96ccb09 Compare June 5, 2026 03:22
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-5-split-clip branch from 32dd0bb to 7f991c4 Compare June 5, 2026 03:22
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.

Clean focused PR — split a media clip at the playhead. +245/-0. Right-sized scope.

Verify before merge:

1. Media-only guard placement

PR body says "media-only guard" and "Split restricted to media only (video/audio/img)". Two layers needed:

  • Server-side (in splitElementInHtml or the API endpoint): rejects split requests on non-media elements with a clean 400, not a silent no-op or partial mutation.
  • Client-side: the right-click menu item + S shortcut don't fire on non-media selections.

If only client-side gates, an adversarial / agent caller can still POST a split mutation against a <div> and get unpredictable behavior. Worth checking both layers.

2. Splitting an element with keyframes

splitElementInHtml clones the element and adjusts timing/media-start. For a <video> with no keyframes, this is straightforward. For a media element that's also a GSAP tween target, what happens to the keyframes?

  • Cloned element gets a new id (probably). Existing GSAP tween targets the old id → no longer targets the new clone. Acceptable? Or should the tween split too?
  • If split happens at t=50% of the clip's window and the keyframes are at 0%/50%/100% of the clip, the post-split clip should arguably retain 50%/100% keyframes (relative) and the pre-split clip should retain 0%/50%. Likely out of scope for this PR (PR body says "media-only"), so the keyframe-target divergence is a non-issue — just confirm the documented contract.

3. Edge cases for the S shortcut

  • Playhead at clip boundary: split at t=0 or t=clip.duration. Should be a no-op or produce zero-length clips? Test plan worth covering.
  • Playhead outside any clip: no-op.
  • Multiple clips selected: split applies to all? Just one? Reject?

4. Phosphor Scissors icon

Verify the icon is already in the project's existing icon set (Phosphor is likely already a dep). If this PR adds Phosphor for the first time, the dep addition belongs in the PR description.

Non-blocking

The splitElementInHtml function is now part of the core source mutation surface. If this gets called from agent flows or external consumers, document its semantics in the JSDoc — particularly the "what gets cloned" (style attrs? class attrs? data-* attrs?) contract.

Review by Jerrai (hyperframes specialist)

…otkey

Add splitElementInHtml to core source mutation helpers — clones an element
at the split time, adjusts data-start/data-duration/data-media-start for
both halves, and inserts the clone after the original.

Wire through: split-element API endpoint, handleTimelineElementSplit in
useTimelineEditing, clip context menu (right-click → Split at Xs), toolbar
split button, and S keyboard shortcut.

Edge cases: locked/implicit clips blocked, media trim offset adjusted by
playback rate, unique ID generation with collision avoidance, undo via
edit history.
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-4b-design-panel-polish branch from 96ccb09 to 343b43b Compare June 5, 2026 05:55
@miguel-heygen miguel-heygen force-pushed the feat/keyframes-5-split-clip branch from 7f991c4 to 524dc79 Compare June 5, 2026 05:55
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