Skip to main content

Overview

The overlays module provides functions to inject and control visual overlays in recorded demos, including an animated cursor and a keyboard HUD that displays pressed keys.

Functions

injectOverlays

Injects cursor and keyboard HUD elements into the page.
function injectOverlays(
  client: CDPClient,
  theme?: OverlayTheme,
  initialPosition?: { x: number; y: number }
): Promise<void>
client
CDPClient
required
The Chrome DevTools Protocol client.
theme
OverlayTheme
Customization options for cursor and HUD appearance.
initialPosition
{ x: number; y: number }
Initial cursor position. Defaults to offscreen.
import { launchChrome, connectCDP, injectOverlays } from '@webreel/core';

const chrome = await launchChrome();
const client = await connectCDP(chrome.port);

await client.Page.navigate({ url: 'https://example.com' });
await injectOverlays(client, {
  cursorSize: 32,
  hud: {
    background: 'rgba(0, 0, 0, 0.7)',
    fontSize: 48
  }
});

showKeys

Displays keys in the keyboard HUD.
function showKeys(client: CDPClient, labels: string[]): Promise<void>
client
CDPClient
required
The Chrome DevTools Protocol client.
labels
string[]
required
Array of key labels to display (e.g., [‘Cmd’, ‘K’]).
import { showKeys } from '@webreel/core';

// Show a keyboard shortcut
await showKeys(client, ['Cmd', 'K']);

// Show a single key
await showKeys(client, ['Enter']);

hideKeys

Hides the keyboard HUD.
function hideKeys(client: CDPClient): Promise<void>
client
CDPClient
required
The Chrome DevTools Protocol client.
import { hideKeys } from '@webreel/core';

await hideKeys(client);

Types

OverlayTheme

Customization options for cursor and HUD appearance.
interface OverlayTheme {
  cursorSvg?: string;
  cursorSize?: number;
  cursorHotspot?: 'top-left' | 'center';
  hud?: {
    background?: string;
    color?: string;
    fontSize?: number;
    fontFamily?: string;
    borderRadius?: number;
    position?: 'top' | 'bottom';
  };
}
cursorSvg
string
SVG markup for the cursor. Defaults to a white arrow with black outline.
cursorSize
number
default:"24"
Cursor size in pixels.
cursorHotspot
'top-left' | 'center'
default:"'top-left'"
Cursor hotspot position for alignment.
hud
object
Keyboard HUD styling options.
background
string
default:"'rgba(0,0,0,0.5)'"
HUD background color (CSS color value).
color
string
default:"'rgba(255,255,255,0.85)'"
Text color (CSS color value).
fontSize
number
default:"56"
Font size in pixels.
fontFamily
string
Font family stack.
borderRadius
number
default:"18"
Border radius in pixels.
position
'top' | 'bottom'
default:"'bottom'"
HUD position on screen.

Default Theme

The default overlay theme is exported as a constant:
import { DEFAULT_HUD_THEME } from '@webreel/core';

console.log(DEFAULT_HUD_THEME);
// {
//   background: 'rgba(0,0,0,0.5)',
//   color: 'rgba(255,255,255,0.85)',
//   fontSize: 56,
//   fontFamily: '"Geist", -apple-system, BlinkMacSystemFont, sans-serif',
//   borderRadius: 18,
//   position: 'bottom'
// }

Theme Customization Examples

Custom Cursor

Use a custom SVG cursor:
const customCursor = `
  <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
    <circle cx="16" cy="16" r="12" fill="#ff0000" stroke="#ffffff" stroke-width="2"/>
  </svg>
`;

await injectOverlays(client, {
  cursorSvg: customCursor,
  cursorSize: 32,
  cursorHotspot: 'center'
});

Minimal HUD

Create a minimal, transparent HUD:
await injectOverlays(client, {
  hud: {
    background: 'rgba(0, 0, 0, 0.3)',
    color: '#ffffff',
    fontSize: 40,
    borderRadius: 12
  }
});

Top-Positioned HUD

Position the HUD at the top of the screen:
await injectOverlays(client, {
  hud: {
    position: 'top'
  }
});

Brand-Themed HUD

Match your brand colors:
await injectOverlays(client, {
  hud: {
    background: 'rgba(99, 102, 241, 0.9)', // Indigo
    color: '#ffffff',
    fontSize: 48,
    fontFamily: '"Inter", sans-serif',
    borderRadius: 16
  }
});

Usage with RecordingContext

Overlays are automatically injected when using the Recorder. You typically don’t need to call these functions directly:
import { Recorder } from '@webreel/core';

const recorder = new Recorder({
  outputPath: 'demo.webm',
  fps: 60,
  theme: {
    hud: {
      background: 'rgba(0, 0, 0, 0.7)'
    }
  }
});

await recorder.start(async (ctx) => {
  await ctx.navigate('https://example.com');
  
  // Keys are shown automatically during typing
  await ctx.typeText('Hello world');
});

Implementation Details

Cursor Animation

The cursor overlay:
  • Uses CSS transforms for smooth animation
  • Has a drop shadow for visibility on any background
  • Is positioned with z-index: 999999 to appear above all content
  • Updates position via transform: translate() for GPU-accelerated movement

Keyboard HUD

The keyboard HUD:
  • Fades in when keys are shown, fades out when hidden
  • Automatically escapes HTML entities in key labels
  • Centers horizontally via transform: translateX(-50%)
  • Adjusts for page zoom level to maintain consistent size
  • Uses flexbox for key label layout

Zoom Compensation

Both overlays automatically adjust for page zoom level by reading document.documentElement.zoom and scaling dimensions accordingly. This ensures overlays remain the correct size regardless of browser zoom.

Build docs developers (and LLMs) love