Closeup
Film any part of a page in close-up, sharp at any size: an element or a region, as a photo or a video, with a drawn cursor that follows yours or plays a path you draw.
// Closeup is a package (npm install @cesarvenzac/closeup), loaded only when
// it's wanted. Film it opens it on the set, ready to record.
const film = () =>
import("@cesarvenzac/closeup").then((closeup) => closeup.open({ pick: set.current }));
// It stays sharp by enlarging the page, not the take: <body> is scaled round
// the pick until the pick fills the window, so the browser draws it large at
// the screen's own resolution. The layout doesn't change, only how big it's drawn.
body.style.transformOrigin = "0 0";
body.style.transform = `translate(${stage.tx}px, ${stage.ty}px) scale(${stage.scale})`;
// Then this tab is captured and cropped to the frame by Region Capture, so
// Closeup's own controls, outside it, never show. Chromium only, for now.
const stream = await navigator.mediaDevices.getDisplayMedia({ video: true, preferCurrentTab: true });
const [track] = stream.getVideoTracks();
await track.cropTo(await CropTarget.fromElement(frame));
// A button of your own on the finished take, as this site's Save to library is.
closeup.addAction({
label: "Save to library",
async run(take, { progress }) {
await upload(take.blob, progress);
return "Saved.";
},
});Sharp at any size
A small part of the screen is small when it's filmed: a 120-pixel button enlarged to fill a 1080-pixel video is a blur. So Closeup enlarges the page instead. A transform on <body> scales it round the pick until the pick fills the window, and the browser draws it large, at the screen's own resolution; the layout doesn't change, only how big it's drawn. Then the tab is captured and cropped to the frame by Region Capture, so Closeup's own controls, outside it, never show, and each frame is laid on its background and recorded.
A cursor for the camera
The real cursor would be filmed small and soft, so it's hidden and a drawing of macOS's stands in, drawn at the take's own size, with a ring at each click if you like. It follows your mouse, or plays a script.
Scripts
The pen opens an editor on the stage, at the size the take is filmed: click where the cursor goes, and drag to pull a curve's handles, as Figma's pen does. Each point moves there, clicks or types, at a hand's pace: Fitts's law for how long it takes, minimum jerk for how it speeds up and slows down. While a script plays, the page hears every move and press as a mouse would tell it, and every :hover and :active rule is copied onto an attribute the cursor sets, so the cloud turns to look, hops and takes its pet on film as it does under your hand.
In your own pages
It's a package with no dependencies: npm install @cesarvenzac/closeup. install() adds ⌥⇧C to a page, open({ pick }) opens it on an element as Film it does, and addAction puts a button of your own on a finished take, as this site's Save to library is. Its source is on GitHub. It films in Chromium browsers on a desktop (Chrome, Edge, Arc, Brave), since Region Capture is theirs.