Skip to main content
A DeckTalk page is an HTML file that the recorder can drive from the narration. The contract consists of a few URL parameters and one global. The file decktalk-runtime.js implements it, and a page can also implement it by hand. Slides are plain HTML that you style yourself, and the runtime adds no styling beyond the stage.

URL parameters

Globals

  • window.__sceneReady is an optional Promise. The recorder awaits it before it starts the clock, so a page can wait for fonts, images, or data. The runtime sets it to document.fonts.ready unless the page has set its own.
  • window.__decktalk exposes { mode, scene, step, cues, fired, catalog, now() }. The catalog field lists every scene and its step ids, and the shots command reads it. The fired field lists the cue ids fired so far.
  • The runtime sets document.body.dataset.done = "1" once the last step has mounted.

Timing in beat mode

  1. The runtime sorts the cues by time. Each cue belongs to a step. The owner is the step with the same id. Failing that, it is the step whose cues list names the cue, or the step whose id is the longest prefix of the cue id. For example, 4.2b1 belongs to 4.2, and 9a belongs to 9.
  2. A step mounts at the earliest of its cues. The first cued step mounts at t=0 regardless, so a section never opens on an empty stage. A step with no cue never shows. The last cued step holds until the recorder stops.
  3. When a step mounts, any element whose data-cue is in the list stays hidden until that cue fires. Every other reveal fires data-at seconds after the mount, and the default is 0. That covers an element with data-at, and an element whose data-cue is not in the list.
  4. When a cue fires, the matching data-cue elements reveal first. Then the step’s on[id] handler runs, and then every DeckTalk.on(id, fn) handler runs.
Without beats=, the page autoplays. The steps mount in order, and each one holds for hold seconds divided by speed. Reveals fire at data-at, and a step’s cues: { id: seconds } object fires handler cues at those seconds after the mount.

Authoring API

The markup attributes inside a step are data-cue, data-at, data-fx, data-dur, data-count, data-type, and data-tex. The data-fx attribute selects the reveal animation. The default is rise, and the others are fade, draw for SVG paths with pathLength="1", drop, pop, dim, and none. The data-dur attribute sets the animation length in seconds, and a count-up defaults to 0.9. The data-count attribute counts the last number in the text up from zero, and data-count="first" counts the first number instead. The data-type attribute types the text at the given milliseconds per character, with a default of 40. The data-tex attribute typesets its value with KaTeX when KaTeX is on the page, and data-display selects display math. The runtime creates #dt-stage, a 1920 by 1080 stage that scales to fit the window, with #dt-cam and #dt-pan inside it. Slides are .dt-slide children of the pan layer. You style the stage and your slides however you like. The runtime’s own CSS uses the dt- prefix.

Build artifacts a page or a script may read

Recording alignment

The recorder covers the page in magenta from its first paint. It opens the page with t0=signal, waits for load, awaits __sceneReady, waits the settle time and at least min_lead_seconds after the recorder was created, and then removes the cover and calls DeckTalk.startClock() in the same tick. The measure command finds the first clean frame after the magenta run and writes it to the sidecar as lead_in_seconds. The assembler trims the recording there, so video t=0 equals narration t=0 to within a frame on every platform. How it works has the picture. A page that implements the contract by hand must honor t0=signal by starting its clock in DeckTalk.startClock() or an equivalent global, or it will start early.