How Shadow Intensity, Border Radius, and Padding Work as Visual Effects in OpenScreen
OpenScreen applies shadow intensity through layered CSS drop-shadow filters, border radius via PixiJS Graphics masks that clip the video sprite, and padding through viewport scaling calculations that inset content from container edges.
OpenScreen is an open-source video editing tool that renders composite video layouts using React and PixiJS. The application exposes three key visual effects—shadow intensity, border radius, and padding—through its Settings panel, transforming numeric slider values into layered CSS filters and geometric masks. These effects are implemented across the VideoPlayback component and the layoutVideoContent utility to create polished, professional video exports.
Shadow Intensity Implementation
The shadow effect is rendered as a CSS filter on the container element that holds the Pixi canvas. In src/components/video-editor/VideoPlayback.tsx, the component constructs a multi-layered drop-shadow chain when showShadow is enabled and shadowIntensity exceeds zero.
The implementation calculates three nested shadow layers with offsets and blur radii proportional to the intensity value (range 0 to 1):
<div
ref={containerRef}
className="absolute inset-0"
style={{
filter:
showShadow && shadowIntensity > 0
? `drop-shadow(0 ${shadowIntensity * 12}px ${shadowIntensity * 48}px rgba(0,0,0,${shadowIntensity * 0.7}))
drop-shadow(0 ${shadowIntensity * 4}px ${shadowIntensity * 16}px rgba(0,0,0,${shadowIntensity * 0.5}))
drop-shadow(0 ${shadowIntensity * 2}px ${shadowIntensity * 8}px rgba(0,0,0,${shadowIntensity * 0.3}))`
: "none",
}}
/>
- First layer: Vertical offset of
shadowIntensity * 12pxwith blur ofshadowIntensity * 48pxand opacity0.7 - Second layer: Offset of
shadowIntensity * 4pxwith blur ofshadowIntensity * 16pxand opacity0.5 - Third layer: Offset of
shadowIntensity * 2pxwith blur ofshadowIntensity * 8pxand opacity0.3
When shadowIntensity is 0, the filter resolves to "none" and no shadow is drawn.
Border Radius Application
Border radius is applied through a PixiJS mask that clips the video content to a rounded rectangle. The layoutVideoContent function in src/components/video-editor/videoPlayback/layoutUtils.ts receives the borderRadius parameter and applies it to a Graphics object that masks the video sprite.
maskGraphics.clear();
maskGraphics.roundRect(
screenRect.x,
screenRect.y,
screenRect.width,
screenRect.height,
compositeLayout.screenCover ? 0 : borderRadius,
);
maskGraphics.fill({ color: 0xffffff });
The roundRect method draws a white fill that serves as the mask geometry. If compositeLayout.screenCover is true, the radius is forced to 0 to maintain sharp corners; otherwise, the supplied borderRadius value (maximum 16 pixels according to the Settings UI) rounds the corners of the visible video area. This mask clips both the main video and any webcam picture-in-picture elements.
Padding Calculation and Viewport Scaling
Padding creates a letterbox effect by scaling down the maximum display dimensions before the video is fitted to the viewport. The logic in src/components/video-editor/videoPlayback/layoutUtils.ts converts the percentage-based padding value into a scale factor.
const effectivePadding = webcamLayoutPreset === "vertical-stack" ? 0 : padding;
const paddingScale = 1.0 - (effectivePadding / 100) * 0.4;
const maxDisplayWidth = width * paddingScale;
const maxDisplayHeight = height * paddingScale;
- Effective padding: Forced to
0when using the vertical-stack webcam preset (full-bleed layout), otherwise uses the slider value (0to100) - Scale calculation:
paddingScale = 1.0 - (effectivePadding / 100) * 0.4, creating a shrink factor between1.0and0.6 - Viewport application: The scaled dimensions are fed into the composite layout algorithm, which determines the final sprite scale
This approach ensures the video appears inset from the container edges while maintaining aspect ratio.
Settings UI Integration
The Settings panel in src/components/video-editor/SettingsPanel.tsx provides sliders that forward values to the VideoEditor component, which then passes them as props to VideoPlayback:
<VideoPlayback
showShadow={shadowIntensity > 0}
shadowIntensity={shadowIntensity}
borderRadius={borderRadius}
padding={padding}
webcamLayoutPreset={webcamLayoutPreset}
// ... other props
/>
The UI enforces constraints through the slider components:
- Border radius: Range
0to16with0.5step increments - Padding: Range
0to100percent, disabled whenwebcamLayoutPreset === "vertical-stack" - Shadow intensity: Range
0to1(implied by the multiplication factors)
Summary
- Shadow intensity uses three nested CSS
drop-shadowfilters inVideoPlayback.tsxwith blur and opacity values calculated as multiples of the intensity slider (0–1) - Border radius creates a clipping mask via
maskGraphics.roundRect()inlayoutUtils.ts, rounding video corners when not in screen-cover mode - Padding applies a
paddingScalefactor (1.0 to 0.6) to the viewport dimensions before layout calculations, creating inset margins - The vertical-stack preset disables padding while preserving shadow and radius effects
- All visual parameters flow from
SettingsPanel.tsxthroughVideoEditorto the rendering components
Frequently Asked Questions
What is the maximum shadow intensity value and how does it affect the blur radius?
The maximum shadow intensity is 1.0 (100%), which produces a blur radius of 48px on the primary shadow layer, 16px on the secondary layer, and 8px on the tertiary layer. These values are calculated by multiplying the intensity by fixed constants (12, 48, 4, 16, 2, and 8 respectively) to create a layered depth effect.
Why is the padding control disabled when using the vertical-stack preset?
The vertical-stack preset enforces a full-bleed layout where the webcam and content occupy distinct vertical regions without margins. The code explicitly sets effectivePadding to 0 when webcamLayoutPreset === "vertical-stack" to prevent the letterbox effect from interfering with the stacked layout geometry.
How does border radius actually clip the video content if it's just a CSS property elsewhere?
Unlike standard CSS border-radius, OpenScreen implements clipping through a PixiJS Graphics mask. The maskGraphics.roundRect() call draws a white shape that serves as an alpha mask for the video sprite. Only pixels within the rounded rectangle are visible, physically clipping the video texture rather than just styling the container corners.
Which source files should I modify to change how these visual effects are calculated?
To modify the shadow rendering, edit src/components/video-editor/VideoPlayback.tsx around lines 1152–1155 where the style.filter prop is constructed. For border radius and padding logic, modify src/components/video-editor/videoPlayback/layoutUtils.ts, specifically the layoutVideoContent function at lines 29–37 for masking and lines 84–90 for padding calculations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →