Coordinates
StageRoutine uses a fixed virtual canvas with stage units. Your presentation looks identical on all displays.
Virtual Viewport
When you call stage.mount("#stage"), StageRoutine creates a 1920×1080 virtual viewport and centers it in your browser window.
- Fixed 16:9 Canvas: You author presentations for a standard
1920×1080virtual canvas. You do not need CSS media queries. - Automatic Scaling: StageRoutine scales and centers the stage to fit any screen, projector, or window size.
- Letterboxing: On displays with non-16:9 aspect ratios, black bars appear around the canvas. Content never stretches or crops.
Stage Units
The stage is 90 units tall. Width follows the aspect ratio, so a 16:9 stage is 160 units wide.
Coordinates range from (0, 0) at the top-left to (160, 90) at the bottom-right. The center is (80, 45).
One unit is the same distance on both axes. This means a radius is a true circle, a diagonal has a predictable angle, and a horizontal gap matches a vertical gap of the same value.
import { Title } from "stageroutine";
const headline = Title("System Overview", {
x: 12,
y: 18,
});
Sizes use the same units:
const card = Card("Service", { width: 30, height: 16 });
A size can also be a CSS length when you want font-relative sizing:
const panel = Card("Notes", { width: "32rem" });
Stage units never need a suffix. If you write a string, it is passed through as CSS.
Element Position vs. Geometric Points
StageRoutine separates element options from geometric points:
-
Element Options (
{ x?, y? }): Elements have separatexandyproperties. This lets layout functions and animations modify one axis without changing the other:const card = Card("Service", { x: 32, y: 32 });card.x = to(128); // Animates horizontal axis onlyYou can also use the
positiontuple shorthand:const card = Card("Service", { position: [32, 32] }); -
Geometric Points (
Point = readonly [x, y]): Standalone vector locations use fixed-length tuples:import { Connector } from "stageroutine";// Connects point [32, 32] to point [128, 45]const line = Connector([32, 32], [128, 45]);
Origin
The origin property defines which point of the element sits on its coordinate. All elements default to "top-left".
scale and rotation pivot around the same point.
| Origin | Description | Typical Use |
|---|---|---|
"top-left" | Top-left corner (default) | Body text, code blocks, tables |
"center" | Exact center | Centered titles, shapes, badges, icons |
"top" | Top center | Stage headers |
"bottom" | Bottom center | Stage footers, bottom bars |
[x, y] | Custom percentage point on the element (e.g. [100, 50]) | Custom alignment |
To center an element on the stage, place it at the stage center and set the origin:
const title = Title("Centered Title", {
position: [80, 45],
origin: "center",
});
To center horizontally while keeping the top edge at a chosen height, use "top":
const heading = Title("Section Heading", {
position: [80, 20],
origin: "top",
});
origin is reactive, so it can animate:
badge.origin = to("center");
Content Alignment
While origin positions the element on the stage, align positions text and child elements inside the element's box.
Containers (Card, Shape) default to "center". Typography elements (Title, Text) default to "left".
Single-axis shorthands center along the opposite axis: "top" means top-center, and "left" means middle-left.
// Centered on the stage, with contents aligned to the top-left inside
const card = Card([Title("Metrics"), Text("All systems operational")], {
position: [80, 45],
origin: "center",
width: 30,
height: 17,
align: "top-left",
});