feat(studio): preserve drop position when dropping blocks onto preview#1010
Merged
Conversation
Blocks dragged from the Blocks panel and dropped onto the composition preview now land at the position where they were dropped, instead of always being placed at (0, 0). The preview viewport converts screen coordinates to composition space using the stage element's bounding rect, accounting for zoom and pan. A visual drop indicator (dashed border overlay) appears while dragging over the preview.
- Rename "Blocks" tab to "Catalog" - Replace fullscreen hover popup with inline preview in main area - Fix z-index: newly added blocks/components use max existing z-index + 1 instead of element count, ensuring they appear on top
Render the catalog hover preview as a full-bleed video inside the preview overlay slot instead of a dimmed card overlay on top.
VITE_STUDIO_* env vars set in the user's shell had no effect when running `hyperframes preview` because the pre-built studio bundle had them baked at Vite build time. The embedded Hono server now collects VITE_STUDIO_* vars from process.env and injects them as a `window.__HF_STUDIO_ENV__` script tag into index.html. The client merges this runtime object on top of the baked `import.meta.env`, so flags like VITE_STUDIO_ENABLE_BLOCKS_PANEL=1 work as expected at runtime.
The DomEditOverlay sits at z-10 with pointer-events:auto over the preview, intercepting all drag events before they reach NLEPreview's viewport. Move block drop handling from NLEPreview up to the wrapper div in NLELayout that contains both the preview and the overlay, so drag-and-drop from the Catalog panel onto the preview area works regardless of inspector state.
Replace fragile regex z-index parsing with getComputedStyle on the preview iframe elements — the same source of truth the inspector uses. Rename "Layer" to "Z-index" in the design panel for clarity.
Blocks were using their own native dimensions (e.g. 1920x1080) instead of the host composition dimensions (e.g. 1280x720), causing them to overflow the viewport and break the layout. The block's iframe scales its content to fit the container, so using host dimensions is correct.
insertTimelineAssetIntoSource now detects the parent indent level and adds the new element with matching child indentation. Block attributes are written one-per-line for readability.
Blocks and components now start at the current playhead position instead of being appended after all existing content. If the new element extends beyond the root composition's data-duration, the root is automatically extended to fit.
8162c90 to
67701df
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
Changes
usePreviewBlockDrop.ts(new) — Extracted hook handling drag-over/drop events on the preview viewport, coordinate conversion from screen → composition space, and block centeringNLEPreview.tsx— Wires the new hook into the preview viewport's drag event handlers and renders the drop indicator overlayNLELayout.tsx— ForwardsonPreviewBlockDropcallback to NLEPreviewStudioPreviewArea.tsx— Accepts and passes the new callbackApp.tsx— CreateshandlePreviewBlockDropthat callsaddBlockToProjectwithvisualPositionblockInstaller.ts— Accepts optionalvisualPositionand uses it for the inserted element'sleft/topCSSTest plan
VITE_STUDIO_ENABLE_BLOCKS_PANEL=true)left/topin the generated HTML corresponds to the drop position in composition space (not 0,0)