Your first scene
This example introduces the complete workflow: create a scene, add tattvas, arrange them, author a timeline, preview it, and export it.
first-scene.ts
import { render } from "veena";
import { Scene, clip, timeline } from "veena/core";
import { Circle, Square } from "veena/primitives";
import { Label } from "veena/text";
class FirstScene extends Scene {
constructor() {
super({ frame: "landscape", width: 1920, height: 1080, background: "#070b14" });
}
override construct() {
const title = this.add(Label("My first Veena scene").height(0.58).color("#ffffff").typewriter());
this.toEdge(title, "up", { margin: 0.75 });
const square = this.add(Square().size(1.4).fill("#7c3aed"), { at: [-3.5, -0.4] });
const circle = this.add(Circle().radius(0.8).fill("#ff6b5f"), { at: [3.5, -0.4] });
const entrance = clip((local) => {
local.animate(title).duration(0.8).typewrite();
local.animate([square, circle]).at(0.25).stagger(0.18).duration(0.8).ease("outCubic").appear();
});
const exchange = clip((local) => {
local.animate(square).duration(1.4).ease("inOutCubic").moveTo([2, -0.4]);
local.animate(circle).duration(1.4).ease("inOutCubic").moveTo([-2, -0.4]);
});
this.play(timeline().then(entrance).then(exchange).wait(0.6));
}
}
render(import.meta.url, FirstScene, { output: "./output/first-scene.mp4" });
Preview and export​
npx tsx first-scene.ts --preview
npx tsx first-scene.ts
Preview does not encode a file. It samples the same timeline as export and supports seeking and replay. The second command writes output/first-scene.mp4.
What happened?​
- The constructor selected a logical
16 × 9landscape frame and a pixel resolution. construct()created and added three tattvas.- Scene layout helpers placed the title relative to the frame.
- Two clips authored reusable blocks of motion.
- The timeline composed those clips sequentially.
render(import.meta.url, ...)bundled the source and ran it in Chromium.
Next, read Mental model and Animations and timelines.