Skip to content

Commit 34f5fc0

Browse files
feat(studio): add pasteboard background to preview viewport (#819)
* feat(studio): add pasteboard background to preview viewport Adds bg-neutral-800 to the preview viewport so the area outside the canvas is visually distinct from the composition content — consistent with professional video editors (Premiere, DaVinci, Figma). * feat(studio): pasteboard background and canvas outline around preview - NLEPreview: viewport gets bg-neutral-700 (#404040) as the pasteboard color surrounding the canvas — distinct from the app chrome (#0a0a0a) - Player wrapper: drop bg-black so the pasteboard shows around the canvas (loading overlays still cover the area with bg-black during load) - Player: set host background to transparent via inline style (overrides :host { background: #000 } in shadow DOM), and inject a style rule into the open shadow root so .hfp-container has overflow:visible and the canvas iframe gets a thin white ring + soft drop-shadow — making the canvas boundary legible against the pasteboard
1 parent 7585f79 commit 34f5fc0

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

packages/studio/src/components/nle/NLEPreview.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ export const NLEPreview = memo(function NLEPreview({
264264
<div className="flex flex-col h-full min-h-0">
265265
<div
266266
ref={viewportRef}
267-
className="relative flex-1 flex items-center justify-center p-2 overflow-hidden min-h-0 outline-none focus:ring-1 focus:ring-studio-accent/40"
267+
className="relative flex-1 flex items-center justify-center p-2 overflow-hidden min-h-0 outline-none focus:ring-1 focus:ring-studio-accent/40 bg-neutral-700"
268268
tabIndex={0}
269269
aria-label="Composition preview"
270270
onPointerDown={handlePointerDown}

packages/studio/src/player/components/Player.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,21 @@ export const Player = forwardRef<HTMLIFrameElement, PlayerProps>(
163163
player.style.width = "100%";
164164
player.style.height = "100%";
165165
player.style.display = "block";
166+
player.style.background = "transparent";
166167
container.appendChild(player);
168+
169+
// Inject pasteboard shadow: let the shadow around the canvas bleed
170+
// into the surrounding pasteboard area (overflow: visible on the container)
171+
// and add a subtle outline + drop-shadow so the canvas boundary reads
172+
// against the gray pasteboard, consistent with professional editors.
173+
if (player.shadowRoot) {
174+
const pasteboardStyle = document.createElement("style");
175+
pasteboardStyle.textContent =
176+
".hfp-container{overflow:visible}" +
177+
".hfp-iframe{box-shadow:0 0 0 1px rgba(255,255,255,0.08),0 4px 32px rgba(0,0,0,.7)}";
178+
player.shadowRoot.appendChild(pasteboardStyle);
179+
}
180+
167181
enableInteractiveIframe(player);
168182

169183
// Bridge the inner iframe to the forwarded ref for useTimelinePlayer.
@@ -309,7 +323,7 @@ export const Player = forwardRef<HTMLIFrameElement, PlayerProps>(
309323

310324
return (
311325
<div
312-
className="relative w-full h-full max-w-full max-h-full overflow-hidden bg-black flex items-center justify-center"
326+
className="relative w-full h-full max-w-full max-h-full overflow-hidden flex items-center justify-center"
313327
style={style}
314328
>
315329
<div ref={containerRef} className="w-full h-full" />

0 commit comments

Comments
 (0)