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 * 12px with blur of shadowIntensity * 48px and opacity 0.7
  • Second layer: Offset of shadowIntensity * 4px with blur of shadowIntensity * 16px and opacity 0.5
  • Third layer: Offset of shadowIntensity * 2px with blur of shadowIntensity * 8px and opacity 0.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 0 when using the vertical-stack webcam preset (full-bleed layout), otherwise uses the slider value (0 to 100)
  • Scale calculation: paddingScale = 1.0 - (effectivePadding / 100) * 0.4, creating a shrink factor between 1.0 and 0.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 0 to 16 with 0.5 step increments
  • Padding: Range 0 to 100 percent, disabled when webcamLayoutPreset === "vertical-stack"
  • Shadow intensity: Range 0 to 1 (implied by the multiplication factors)

Summary

  • Shadow intensity uses three nested CSS drop-shadow filters in VideoPlayback.tsx with blur and opacity values calculated as multiples of the intensity slider (0–1)
  • Border radius creates a clipping mask via maskGraphics.roundRect() in layoutUtils.ts, rounding video corners when not in screen-cover mode
  • Padding applies a paddingScale factor (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.tsx through VideoEditor to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →