# How OpenScreen's Wallpaper System Supports Solid Colors, CSS Gradients, and Custom Images

> Learn how OpenScreen's wallpaper system supports solid colors, CSS gradients, and custom images by treating the wallpaper prop as a generic CSS background value.

- Repository: [Sid/openscreen](https://github.com/siddharthvaddem/openscreen)
- Tags: internals
- Published: 2026-04-03

---

**OpenScreen treats the `wallpaper` prop as a generic CSS background value, using string prefix detection to automatically distinguish between hex colors, gradient definitions, data URLs, and image file paths.**

OpenScreen is an open-source video editor that renders dynamic backgrounds behind the video canvas using a flexible, prop-driven wallpaper system. The implementation in [`src/components/video-editor/VideoPlayback.tsx`](https://github.com/siddharthvaddem/openscreen/blob/main/src/components/video-editor/VideoPlayback.tsx) resolves background values through a three-stage pipeline that natively supports everything from simple hex codes to complex CSS gradients and user-uploaded images without server-side processing.

## Three-Stage Wallpaper Resolution Pipeline

The OpenScreen wallpaper system processes input through distinct resolution stages before DOM rendering.

### Default Fallback Mechanism

When no `wallpaper` prop is supplied, the component automatically loads the first bundled asset. The code in [`VideoPlayback.tsx`](https://github.com/siddharthvaddem/openscreen/blob/main/VideoPlayback.tsx) (lines 1054-1059) invokes `getAssetPath` to resolve `wallpapers/wallpaper1.jpg` as the default background, ensuring the video editor always presents a visual backdrop.

### String Prefix Detection Logic

A `useEffect` hook monitoring the `wallpaper` prop implements prefix-based routing (lines 1060-1094) to interpret the input string:

- **Solid colors** – Strings starting with `#` are applied directly as CSS color values (e.g., `#2a9d8f` or `#fff`).
- **CSS gradients** – Values beginning with `linear-gradient` or `radial-gradient` are injected unchanged into the `background` property, supporting any valid CSS gradient syntax.
- **Data URLs** – Strings starting with `data:` (generated from FileReader API uploads) render user-provided images immediately without external requests.
- **Absolute paths** – Values beginning with `http`, `file://`, or `/` are treated as image sources. Paths starting with `/` are resolved through `getAssetPath` (defined in [`src/lib/assetPath.ts`](https://github.com/siddharthvaddem/openscreen/blob/main/src/lib/assetPath.ts)) to handle bundled assets correctly across development and Electron production builds.

After resolution, the final string is stored in the `resolvedWallpaper` state variable.

### DOM Rendering Layer

The background renders as a plain `<div>` positioned behind the Pixi canvas (lines 1119-1126). The component conditionally applies `backgroundImage` for URL-based sources or `background` for color and gradient strings. An optional CSS blur filter (`showBlur`) can overlay the wallpaper, though the background layer remains separate from the Pixi rendering pipeline to maintain video processing performance.

## SettingsPanel User Interface

The wallpaper selection interface in [`src/components/video-editor/SettingsPanel.tsx`](https://github.com/siddharthvaddem/openscreen/blob/main/src/components/video-editor/SettingsPanel.tsx) provides three distinct input methods, all funneling through the `onWallpaperChange` callback to update the `VideoPlayback` component's state.

### Image Selection Tab

The **Image** tab displays bundled wallpapers resolved via `getAssetPath` alongside custom uploads stored as data URLs (lines 75-98). Users select from predefined assets or uploaded files, with selections passed as strings to `onWallpaperChange`.

### Color Picker Integration

The **Color** tab utilizes `@uiw/react-color-block` to generate hex strings. When users select a color, the component calls `onWallpaperChange` with the hex value (lines 62-70), which the resolution pipeline in [`VideoPlayback.tsx`](https://github.com/siddharthvaddem/openscreen/blob/main/VideoPlayback.tsx) treats as a solid color background.

### Gradient Preset Grid

The **Gradient** tab presents a grid of predefined CSS gradient strings. Clicking any tile invokes `onWallpaperChange` with the raw gradient definition (lines 79-92), allowing complex multi-stop gradients without requiring users to manually write CSS syntax.

## Implementation Examples

Pass a hex code for a solid color background:

```tsx
<VideoPlayback
  videoPath="video.mp4"
  wallpaper="#2a9d8f"
/>

```

Use any valid CSS gradient string:

```tsx
<VideoPlayback
  videoPath="video.mp4"
  wallpaper="linear-gradient(120deg, #ff9a9e 0%, #fad0c4 100%)"
/>

```

Render a custom uploaded image as a data URL:

```tsx
const dataUrl = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ…";
<VideoPlayback
  videoPath="video.mp4"
  wallpaper={dataUrl}
/>

```

Reference a bundled wallpaper by path:

```tsx
<VideoPlayback
  videoPath="video.mp4"
  wallpaper="/wallpapers/wallpaper5.jpg"
/>

```

## Summary

- The OpenScreen wallpaper system uses **string prefix detection** in [`VideoPlayback.tsx`](https://github.com/siddharthvaddem/openscreen/blob/main/VideoPlayback.tsx) to route values through appropriate resolution logic without external dependencies.
- **Solid colors** require only a hex string starting with `#`, processed directly as CSS color values.
- **CSS gradients** support any valid `linear-gradient` or `radial-gradient` syntax passed verbatim to the background property.
- **Custom images** work as base64 data URLs from uploads or absolute paths resolved through `getAssetPath` for bundled assets.
- The rendering layer uses standard DOM elements positioned behind the Pixi canvas, with optional CSS blur filters that don't affect video performance.
- The [`SettingsPanel.tsx`](https://github.com/siddharthvaddem/openscreen/blob/main/SettingsPanel.tsx) component unifies selection through the `onWallpaperChange` callback, supporting Image, Color, and Gradient input modes.

## Frequently Asked Questions

### How does OpenScreen handle uploaded image files?

OpenScreen converts uploaded files to base64 data URLs using the FileReader API. These strings, identified by the `data:` prefix, bypass server processing and render immediately as background images in the `VideoPlayback` component according to the resolution logic at lines 1060-1094.

### Can I use radial gradients or only linear gradients?

Both radial and linear gradients are fully supported. The resolution logic specifically checks for strings starting with `linear-gradient` or `radial-gradient` and passes them directly to the CSS `background` property without modification, allowing any valid CSS gradient syntax.

### What happens if I provide an invalid wallpaper path?

If the `wallpaper` prop doesn't match the expected prefix patterns (hex `#`, gradient keywords, `data:`, `http`, `file://`, or `/`), the component may fail to render a visible background. The system relies on explicit prefix matching in the `useEffect` hook, so invalid strings won't trigger the default fallback mechanism reserved for undefined props.

### Is the wallpaper rendered inside the Pixi canvas?

No. Wallpapers render in a separate DOM `<div>` layer positioned behind the Pixi canvas (lines 1119-1126). This architectural separation allows CSS filters like `showBlur` to apply to the background without impacting video processing performance or canvas rendering fidelity.