feat(studio): MotionPathPlugin arc motion + design panel redesign#1232
Open
miguel-heygen wants to merge 34 commits into
Open
feat(studio): MotionPathPlugin arc motion + design panel redesign#1232miguel-heygen wants to merge 34 commits into
miguel-heygen wants to merge 34 commits into
Conversation
…ache on deletion Two stability fixes for the keyframe editing flow: 1. Code editor refreshes after GSAP script mutations via onFileContentChanged callback that syncs result.after to editingFile state. 2. Keyframe cache clears on deletion: commitMutation removes cache entries for elements without keyframes, usePopulateKeyframeCacheForFile clears stale entries before repopulating. Also fixes pre-existing typecheck: handleGsapMaterializeKeyframes optional in TimelineToolbar DomEditSessionSlice.
Add border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius to CURATED_STYLE_PROPERTIES. The Radius section auto-detects uniform vs per-corner mode: single slider when all corners match, 4 MetricFields (TL/TR/BR/BL) when they differ.
Figma-style SVG corner picker showing a rounded rectangle preview with 4 corner handles. Link/unlink toggle switches between uniform mode (single field) and per-corner mode (4 fields TL/TR/BL/BR).
When GSAP animates borderRadius, read the per-corner computed styles from the iframe element and pass them to the BorderRadiusEditor. The design panel now shows interpolated border-radius values as the playhead moves through GSAP keyframes.
When the code editor saves changes (via refreshKey), the GSAP keyframe cache was not invalidated because code-tab edits bypass commitMutation. Watch refreshKey changes and bump gsapCacheVersion so timeline diamonds clear when keyframes are manually removed in the code editor.
Closes #1219 On 8GB RAM machines, renders time out at 5% with `Runtime.callFunctionOn timed out` during the duration probe. User-set timeout env vars (`PRODUCER_PUPPETEER_PROTOCOL_TIMEOUT_MS`) are silently ignored by the calibration path, and there are no CLI flags to control timeouts directly. 1. **Calibration timeout cap overrides user settings** — `createCaptureCalibrationConfig` used `Math.min(cfg.protocolTimeout, 30_000)`, meaning even if the user set 300s, calibration still capped at 30s. On slow hardware this causes unnecessary timeouts. 2. **8GB systems get no low-memory treatment** — `getLowMemoryFlags()`, `getGpuMemBudgetMb()`, `memoryAdaptiveCacheLimit()`, and `memoryAdaptiveCacheBytesMb()` all used `< 8192` as the threshold. Systems reporting exactly 8192 MB (common for 8GB machines) fell through to the "plenty of memory" path, getting no Chrome heap reduction or cache limits. 3. **No CLI flags for key timeouts** — Users had to discover the correct env var names (`PRODUCER_PUPPETEER_PROTOCOL_TIMEOUT_MS`, `PRODUCER_PLAYER_READY_TIMEOUT_MS`) by reading source. The non-existent `PUPPETEER_PROTOCOL_TIMEOUT` and `--browser-timeout` were common guesses that did nothing. - `captureCost.ts`: `Math.min` → `Math.max` so the 30s calibration default is a floor, not a ceiling. User-set higher timeouts are now respected. - `browserManager.ts`: `>= 8192` → `> 8192` in `getLowMemoryFlags()` and `<= 8192` in `getGpuMemBudgetMb()` so 8GB systems get reduced Chrome heap and GPU memory budget. - `config.ts`: `< 8192` → `<= 8192` in `memoryAdaptiveCacheLimit()` and `memoryAdaptiveCacheBytesMb()` so 8GB systems get reduced frame cache limits. - `render.ts`: Added `--protocol-timeout <ms>` and `--player-ready-timeout <ms>` CLI flags, wired through `resolveConfig` overrides. - Updated calibration tests to match the new floor-not-ceiling behavior. - Added fallow suppressions for pre-existing unused exports in `captureCost.ts`. - [x] Engine config tests pass (`vitest run src/config.test.ts`) - [x] Browser manager tests pass (`vitest run src/services/browserManager.test.ts`) - [x] Calibration safeguard tests pass (4/4 in `renderOrchestrator.test.ts`) - [x] TypeScript compiles cleanly for engine and cli packages - [ ] CI pipeline
* fix: add progress logging during silent render pipeline stages The render pipeline only updates progress at stage boundaries (5%, 10%, 25%), leaving multi-minute gaps with zero log output on low-memory hardware. This adds log.info calls at key sub-steps within the three silent stages: - Probe stage (5%): browser launch, session initialization, duration discovery, media asset discovery, audio volume automation, video visibility window detection - Video extraction (10%): per-video extraction progress - Calibration (25%): browser launch, session initialization, per-frame calibration progress, final cost estimate Also adds 30-second heartbeat timers for the two initializeSession calls (probe and calibration) that can individually take minutes on constrained hardware. Closes #1218 * fix: resolve CI failures in typecheck, runtime seek test, and timeline test - Make handleGsapMaterializeKeyframes optional in DomEditSessionSlice and use optional chaining at the call site (not yet wired) - Update GSAP adapter seek test to expect nudge+seek pattern (totalTime with suppressEvents:true followed by actual seek) - Fix Timeline canvas height test to use TRACK_H constant (48) instead of stale hardcoded value (72) * refactor: extract helpers to meet 600-line file size limit - App.tsx (603→594): extract StudioToast component - useDomEditSession.ts (688→600): extract useGsapSelectionHandlers hook - Timeline.tsx (614→557): extract useTimelineAssetDrop hook - PropertyPanel.tsx (647→584): extract TimingSection to propertyPanelTimingSection * style: fix formatting in TimelineToolbar
…CDN loading Remove MotionPathPlugin and registerPlugin from FORBIDDEN_GSAP_PATTERNS — each dangerous plugin (ScrollTrigger, etc.) is already individually banned, so the blanket registerPlugin ban was redundant. Add MOTIONPATH_CDN constant and conditionally include the MotionPathPlugin script tag in generated HTML when the GSAP script references motionPath.
Add ArcPathSegment, ArcPathConfig types to gsapSerialize.ts. Extend GsapAnimation with optional arcPath field. In gsapParser, parse the motionPath property from tween vars — extract waypoints into keyframe x/y properties and control points into ArcPathSegment. Supports both curviness-based (waypoint array) and type:"cubic" (explicit bezier control points) formats. When motionPath coexists with keyframes, waypoint positions are merged into existing keyframes.
Add setArcPathInScript, updateArcSegmentInScript, removeArcPathFromScript to gsapParser.ts. These operate at the AST level via recast, following the existing keyframe mutation pattern. setArcPath extracts x/y from keyframes into a motionPath object with type:"cubic" and interleaved control points, strips x/y from keyframe nodes. updateArcSegment rebuilds the motionPath with updated control points for a specific segment. removeArcPath strips the motionPath property from the tween.
Add set-arc-path, update-arc-segment, remove-arc-path mutation types to GsapMutationRequest union. Wire switch cases calling the parser functions from U3. Add setArcPath, updateArcSegment, removeArcPath wrappers to useGsapScriptCommits with soft reload enabled.
New ArcPathControls component with toggle, per-segment curviness sliders (0-3 range, 0.1 step), auto-rotate toggle, and per-segment reset button. Integrated into AnimationCard below property list, visible when animation has keyframes. Full callback wiring through GsapAnimationSection → PropertyPanel → StudioRightPanel → DomEditContext → useDomEditSession → useGsapScriptCommits → API routes → parser AST mutations.
…ization Create MotionPathOverlay component that renders curved SVG paths through keyframe waypoints with anchor circles and control point handles. Supports both curviness-auto-generated and explicit cubic bezier control points. The overlay renders as an absolute-positioned SVG layer with pointer-events for future drag interaction on control point handles.
Register MotionPathPlugin alongside CustomEase in the studio motion render script when the plugin is available on window. In soft reload, register the plugin before injecting the replacement IIFE script so motionPath tweens are recognized by GSAP during timeline rebuild.
…lements After binding the root timeline, iterate its children tweens and stamp data-start and data-duration attributes on each target element that lacks them. This allows the Studio timeline to discover individual animated elements from raw GSAP compositions without requiring manual HTML attributes. The duration is computed as the span from earliest to latest tween touching each target.
…ration Elements in the initial DOM are always visible — their tween start times define when animations begin, not when the element appears. Set data-start to 0 and data-duration to the root composition duration for all GSAP-targeted elements that lack explicit timing attributes.
The runtime keyframe scanner now creates synthetic keyframe entries from flat tl.to() calls, not just percentage keyframes. Each tween's start position on the timeline becomes a diamond marker. Multiple tweens targeting the same element accumulate into a single keyframe set. This makes all GSAP-animated elements show their tween events on the timeline.
…thetic Extract design tokens to panelTokens.ts. Unify accent color to #3B82F6 across all controls (replaces 4 inconsistent colors: emerald, teal, purple, orange). Restyle primitives: inputs rounded-md (6px, was 12px), slider tracks 2px (was 8px), toggles 28x16px with 150ms transitions, section headers 10px uppercase with 15% opacity separators. Add tabular-nums to numeric displays. Section content padding widened to 20px. Labels drop uppercase (only section headers are uppercase). Focus ring brightened.
…panel Section headers change from 10px uppercase with wide tracking to 12px title-case bold (Figma UI3 pattern). Labels, tag badges, and color picker sub-labels all drop uppercase and tracking — cleaner, more readable, less "spreadsheet" feel.
Replace all blue accent (#3B82F6) references with teal (#2DD4BF) across the design panel: toggles, slider fills, ease curve, motion path overlay, border radius corners, keyframe diamonds, fill checkbox, color picker focus rings, animation card badges. Single teal accent throughout.
Add panel-* color namespace to tailwind.config.js (panel-bg, panel-input,
panel-surface, panel-hover, panel-border, panel-text-1 through panel-text-5,
panel-accent, panel-danger). Replace all hardcoded hex in Tailwind classes
with panel-* tokens. Keep panelTokens.ts minimal — only the values needed
for inline style={{}} in toggles. FIELD uses bg-panel-input, LABEL uses
text-panel-text-3, Section uses border-panel-border + text-panel-text-1.
Drop the rounded-xl border bg-neutral-900/60 card wrapper from text field rows. Content sits directly in the section — flat, no visual container boxing. Matches the Figma-style flat section approach.
LayersPanel: bg-panel-bg, border-panel-border, text-panel-text-*, selected state uses panel-accent, tag badges use panel-hover. RenderQueue and RenderQueueItem: all neutral-* colors replaced with panel-* tokens. Consistent dark instrument aesthetic across all three right panel tabs.
Render controls: compact rounded-md selects in a flow row (format, res, fps, quality), full-width teal Export button below. Section header with "Export" title and "Clear history" link. Header: add teal "Export" button next to Inspector that switches to the Renders tab and opens the right panel.
…plication Remove "Export" section header (redundant with header button). Render settings now a clean 2×2 grid: Format, Resolution, Frame rate, Quality — each with a label above. Full-width Export button at bottom. Render items use panel-accent for progress bar and download hover. Clear button moves inline with the job list count.
Collaborator
Author
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
6 tasks
84d75b7 to
60573ad
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
MotionPathPlugin Arc Motion
ArcPathConfigtypes + parser recognition (waypoints, control points, curviness, autoRotate)set-arc-path,update-arc-segment,remove-arc-path)Runtime Timeline Discovery
data-start/data-durationon GSAP-targeted elementskeyframes: {}format)Design Panel Redesign
panel-*color tokens in Tailwind config#2DD4BFunified accent (replaces 4 inconsistent colors)bg-panel-inputfields with teal focus ringLayers & Renders Panel
panel-*tokensTest plan