Combo

Studio

Interaction workspace and canvas management.

The Studio is the interactive workspace for your video editing. It manages the visual canvas, selection, transformation, and real-time editing of clips and objects.

Creating a Studio

import { Studio } from "@designcombo/video";

const studio = new Studio({
  width: 1920,
  height: 1080,
  fps: 30,
  bgColor: "#ffffff",
  canvas: document.getElementById("canvas") as HTMLCanvasElement,
});

// The studio initializes its PixiJS application automatically on construction (via initPixiApp).
// You can wait for it to be ready:
await studio.ready;

Configuration Options

IStudioOpts

interface IStudioOpts {
  width: number;
  height: number;
  fps?: number;
  bgColor?: string;
  canvas?: HTMLCanvasElement;
  interactivity?: boolean;
}

Interactive Controls

The Studio supports interactive transformations (moving, scaling, rotating) by default. You can disable this via the interactivity option:

const studio = new Studio({
  width: 1920,
  height: 1080,
  interactivity: false, // Disable all interactive controls
});

Adding and Removing Objects

addClip()

Add clips to the studio:

import { Image } from "@designcombo/video";

const image = await Image.fromUrl("photo.jpg");
studio.addClip(image);

removeClip()

Remove clips from the studio:

studio.removeClip(image.id);

updateClip() / updateClips()

Update clip properties. updateClips is preferred for batch updates to avoid multiple re-renders.

// Update single clip
await studio.updateClip(clip.id, { left: 100, opacity: 0.5 });

// Batch update multiple clips
await studio.updateClips([
  { id: clip1.id, updates: { left: 100 } },
  { id: clip2.id, updates: { angle: 45 } }
]);

addTransition()

Adds a transition between two clips.

await studio.addTransition("fade", 2000000, fromClipId, toClipId);

Selection Management

selectedClips

Get the currently selected clips:

const selected = studio.selectedClips; // Set<IClip>
if (selected.size > 0) {
  console.log(`${selected.size} clips selected`);
}

Transformation

The studio automatically shows transform controls when objects are selected. Users can:

  • Drag to move objects
  • Drag corners to resize
  • Drag rotation handle to rotate
  • Selection box for multi-select

Studio Events

The studio implements an event emitter that notifies you about changes in the workspace.

studio.on('selection:created', ({ selected }) => {
  console.log('Selection created', selected);
});

studio.on('clip:added', ({ clip, trackId }) => {
  console.log('Clip added', clip.id);
});

studio.on('currentTime', ({ currentTime }) => {
  // currentTime is in microseconds
  console.log('Current time:', currentTime);
});

Selection Operations

The Studio provides methods to perform operations on the currently selected clips.

deleteSelected()

Removes all selected clips.

await studio.deleteSelected();

duplicateSelected()

Duplicates all selected clips.

await studio.duplicateSelected();

splitSelected()

Splits all selected clips at the current time (or a specified time).

await studio.splitSelected();
// or
await studio.splitSelected(5000000); // Split at 5s

trimSelected()

Trims the selected clips.

await studio.trimSelected(2000000); // Trim 2s

Artboard

The studio includes an internal artboard (composition area) where clips are placed. The artboard:

  • Clips child objects with a mask to match the studio dimensions
  • Centers in the canvas viewport
  • Can have a custom background color
const studio = new Studio({
  width: 1920,
  height: 1080,
  bgColor: "#ffffff",
});

Coordinate Conversion

screenToArtboard()

Convert screen coordinates to artboard coordinates:

const artboardPos = studio.screenToArtboard(mouseX, mouseY);

artboardToScreen()

Convert artboard coordinates to screen coordinates:

const screenPos = studio.artboardToScreen(objectX, objectY);

Cleanup

destroy()

Clean up and destroy the studio:

studio.destroy();

This will:

  • Remove all event listeners
  • Destroy the PixiJS application
  • Clean up all containers
  • Free memory

Complete Example

import { Studio, Image, Text } from "@designcombo/video";

// Create studio
const studio = new Studio({
  width: 1920,
  height: 1080,
  bgColor: "#222222",
  canvas: document.querySelector("canvas") as HTMLCanvasElement,
});

// Wait for studio to be ready
await studio.ready;

// Add clips
const image = await Image.fromUrl("photo.jpg");
image.set({
  left: 200,
  top: 200,
  width: 400,
  height: 300,
});

const text = new Text("Hello World", {
  fontSize: 100,
  fill: "#ffffff",
});
text.set({
  left: 800,
  top: 500,
});

studio.addClip(image);
studio.addClip(text);

// Listen for selection changes
studio.on('selection:created', ({ selected }) => {
  console.log(`${selected.length} clips selected`);
});

// Later: cleanup
// studio.destroy();

Next Steps

On this page