decktalk-runtime.js is the script that plays a DeckTalk page. It mounts the steps of a scene and
makes elements appear on their cues. This page lists its modes, URL parameters, functions, data
attributes, fields, CSS hooks, and warnings. The page contract explains
how the parts work together.
Include the runtime before the scene definitions. After you upgrade DeckTalk, run
decktalk runtime to refresh the project’s copy.
deck/index.html
Modes
The URL picks the mode. In prose these docs write index mode, autoplay, cue mode, and freeze mode.
Note:
step wins over scene and beats. With beats and no registered scene, the scene that
owns the earliest cue plays. Cue ownership gives the
ownership and mount rules of cue mode.
URL parameters
Note: An unknown
scene shows the index with the note unknown scene N. An unknown step shows
the index with the note unknown step ID. Neither adds a warning. The catalog still exists, so the
recorder records the index with no PAGE ERROR.
Note: The runtime sorts the beats pairs by time and splits each pair at its last @. It skips a
pair whose seconds are not a number. Write every pair as id@seconds.
Note: The recorder builds words from build/audio/timeline.json, in seconds after the section
start. It removes commas and @ from each word. It builds prevwords the same way from the section
before, and leaves it out for the first section or when the section before has no words.
Note: In freeze mode, the step’s cues fire in autoplay order. A cue in a cues list, with no
seconds, fires after the timed cues. Animations take no time. A count-up shows its final value, a
typewriter shows its full text, and a data-sync element shows whole.
Note: With cue or before, only the cues that fire run their handlers. A cue or before id that is not one of the step’s cues adds the warning cue "ID" is not one of step STEP's cues, and every cue fires. enter still gets ctx.frozen as
true, so a figure that enter draws in its end state shows that state at every cue. A cue that is
not one of the step’s cues adds a warning, and the whole step freezes. In the scaffold,
?step=2.1&cue=2.1aloud shows the script card and the waveform with its word times. It hides the
outlines that join the cue word to its drawing, which wait for 2.1word, and the arrow to the slide
card, which waits for 2.1follows. decktalk shots --step 2.1 --cue 2.1aloud opens that URL.
DeckTalk.scene(id, definition)
DeckTalk.scene registers a scene and returns DeckTalk, so calls chain. The scenes start on
DOMContentLoaded when at least one scene is registered.
Scene fields
Note: A push lasts the autoplay total in autoplay, or the last cue time plus 8 s in cue mode. It
lasts at least 4 s. Freeze mode shows no push. Add a camera push
says when to use one.
Step fields
Note: In autoplay, a
data-cue element appears at its data-at time, or when the cues object
fires its cue, whichever comes first. data-at defaults to 0. So a browser preview shows the
element as soon as its step mounts.
Note: In autoplay, a time in cues at or past hold adds a warning, because that cue fires after
the next step mounts. The last step of a scene never warns. A seconds value that is not a number
counts as 0.
Note: render gets the runtime’s own scene and step objects. Inside its template literal, write
every backslash twice (data-tex).
Note: enter gets the handler context with id and step set to the step id,
and at set to the mount time. Keep the state that cue handlers need on the slide element, as in
slide.fig = setup(slide, ctx.frozen). An exception in enter goes to console.error, and the
scene goes on.
Handler context
A step’senter, its on[id] handlers, and every DeckTalk.on(id, fn) handler get two arguments.
The first is the slide element of the mounted step. The second is a context object with these
fields. A handler that takes no arguments still works.
deck/index.html
DeckTalk methods and properties
Note: A handler that
DeckTalk.on registers also stops the unknown cue id warning for its id.
Call DeckTalk.start() yourself only for a scene that you register after DOMContentLoaded.
Data attributes
Put these attributes on elements inside the HTML of a step.
Note: In cue mode, a
data-cue that ?beats= does not list adds a warning. That element appears at
its data-at time. In freeze mode, every element appears at once, except elements of cues after the
cue parameter.
Note: data-count, data-type, and data-sync run when their element appears. Each one needs
data-cue or data-at on the same element. Without either, the effect never runs, and the page
warns.
Note: data-count keeps the decimal places and thousands commas of the number, so 1,250.5
counts with one decimal and a comma. The rest of the text stays in place. The count eases out over
data-dur, or 0.9 s. data-type keeps the element at the size of its finished text, so nothing
around it moves.
data-fx
Choose a reveal effect says where each effect works
well.
data-sync
An element with data-sync shows its words one at a time, each at the moment the voice says it.
These rules apply:
- The element also needs
data-cueordata-at. Without either, the words never sync, and the page warns. - The text must match the spoken words, word for word. Matching ignores case and every character except a to z and 0 to 9.
- Apostrophes do not count in this match. The
beatsstage keeps apostrophes when it matches a cue phrase. - If the text occurs more than once, the runtime uses the first match that starts at most 1.5 s before the element appears. If every match starts earlier, it uses the last match.
- If nothing matches, the element appears whole, and the page warns.
- Each word appears 20 ms before its start time, with a 0.12 s fade.
- The element gets
data-fx="none"unless it sets its owndata-fx. A reveal effect on the whole element would hide the timing of the words. - Without a
wordsparameter, as in a browser preview, the element appears whole. It also appears whole in freeze mode.
data-tex
The runtime typesets the value of data-tex with KaTeX when window.katex exists. The typeset math
replaces the element’s text. Without KaTeX, the text stays, so write it as a readable fallback.
KaTeX shows a TeX string that it cannot parse in red, and the page warns.
Inside a render template literal, write every backslash twice. JavaScript reads \f, \t, \u,
and \x as escapes. For example, \frac becomes a form feed, and \theta becomes a tab.
\underbrace and \xrightarrow become syntax errors, and a syntax error blanks the page.
deck/index.html
data-tex element and KaTeX is missing, the runtime checks again 5 s later. If
the element is still plain text, the page warns.
window.__decktalk
window.__decktalk holds read-only state for the recorder, decktalk shots, and your own tools.
Note: After a recording, the recorder reads
catalog, warnings, frameGaps, syncLog, cueLog, and longFrames. A
missing or empty catalog is a page error. decktalk shots reads catalog to find every step.
Note: With a numeric t0, the clock starts at load, so narration t=0 is where now() equals
t0. With t0=signal, now() counts from narration t=0.
Note: In frameGaps, at is the value of now() when the gap ended. A gap under the cover has
at equal to -Infinity, and the sidecar field frame_gaps writes it as null. Only the part of
a gap after t=0 counts toward STALLED (decktalk check). So a page
can do slow first work before t=0, such as drawing a canvas figure or a large SVG.
Note: In syncLog, text is the first 24 characters of the text. cueAt is the time the element
appeared, and runAt is the start of its first matched word. n is the number of words, and
firstOn is the time the first word appeared. The sidecar field is sync_log.
Note: In cueLog, every time is in seconds on the narration clock. due is the cue’s time, and ran
is when the runtime fired it. frame is the start of the animation frame that fired it, and next
and after are the starts of the two frames after it. A cue with ran well past due was held up
before its frame. A cue that ran on time but whose next frame started late was held up while its
frame was drawn. The sidecar field is cue_log.
Note: In longFrames, start, render, and presented are seconds on the narration clock, and ms
is the frame’s length. presented is when Chromium showed the frame, or null when the browser does
not report it. The sidecar field is long_frames.
The runtime also sets document.body.dataset.done to "1" when the last step has mounted.
window.__sceneReady
window.__sceneReady is a Promise. The recorder awaits it before it starts the clock. If the page
has not set it, the runtime sets it when the mode starts. The default Promise waits for two things,
in order:
document.fonts.ready.- KaTeX, when the document has a
[data-tex]element or a<script>whosesrccontainskatex. The runtime checks forwindow.katexevery 100 ms, for up to 5 s. Then it typesets the mounted slide. If KaTeX never loads, the page warns, and the elements keep their text.
DOMContentLoaded listener. Register the
listener after the runtime’s <script> tag. The runtime sets its Promise in its own listener, which
runs first. The scaffold’s deck/lesson.html waits this way for its fonts and three animation
frames, so its figure has painted before t=0.
deck/lesson.html
window.__sceneReady in a script that runs before
DOMContentLoaded. A replacement removes the KaTeX wait. If the page uses data-tex, wait for
window.katex yourself. Wait for a screenshot to load
shows how to extend the wait for an image.
CSS hooks
The runtime adds a<style id="dt-style"> element. Its rules use only names that start with dt-.
Note: A page can supply its own
#dt-stage, as the scaffold’s deck/lesson.html does. The runtime
adds #dt-cam after the page’s content, so the slides draw on top of it.
Note: The first slide moves in 24 px from the right as it fades in over 0.3 s. The scaffold turns
this off with #dt-pan > .dt-slide.dt-first { animation: none; }, so a section opens on a full frame.
Warnings
The runtime lists each warning one time inwindow.__decktalk.warnings. The console prints it with
the prefix decktalk: . In the messages below, <id>, <step>, and <n> stand for real values.
An
enter function or a handler that throws goes to console.error, and the scene goes on. A
render function that throws is an uncaught page error. The recorder logs it, and check reports
PAGE ERROR.
Related
- Learn how a page plays: The page contract
- Size a slide and choose reveal effects: Design a slide
- Write a page without the runtime: Write a page by hand