summaryrefslogtreecommitdiff
path: root/docs/site/site.typ
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 13:24:07 -0300
committerGabriel Schneider <[email protected]>2026-10-01 13:34:00 -0300
commit52820eb70af788db49735292e2a9ad89cbf1e457 (patch)
treedfbefd44cffc76750b477c16c42a181b65963124 /docs/site/site.typ
parent3d3929960bdc51aa491bdbb5cf83d1b9ab8bb197 (diff)
downloadpardes-52820eb70af788db49735292e2a9ad89cbf1e457.tar.gz
pardes-52820eb70af788db49735292e2a9ad89cbf1e457.zip
Every recording on the landing plays by itself, and only while it is on screen
The GUI clips are autoplay muted loop playsinline with their controls, and every terminal cast autoplays and loops. A few lines of script watch them with an IntersectionObserver, playing each while a quarter of it is in view and pausing it when it leaves; without the script the videos still autoplay. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'docs/site/site.typ')
-rw-r--r--docs/site/site.typ28
1 files changed, 23 insertions, 5 deletions
diff --git a/docs/site/site.typ b/docs/site/site.typ
index b308853d..e0cd9d4d 100644
--- a/docs/site/site.typ
+++ b/docs/site/site.typ
@@ -128,15 +128,17 @@
#doc-links.update(true)
-#let video(c) = el("video", (poster: "media/" + c.name + ".png", muted: "", loop: "", playsinline: "",
- controls: "", preload: "none"))[
+// Every recording plays by itself; the script below plays each only while
+// it is on screen. Without the script, `autoplay` still plays them.
+#let video(c) = el("video", (poster: "media/" + c.name + ".png", autoplay: "", muted: "", loop: "", playsinline: "",
+ controls: ""))[
#el("source", (src: "media/" + c.name + ".webm", type: "video/webm"))[]
#el("source", (src: "media/" + c.name + ".mp4", type: "video/mp4"))[]
]
#let placeholder = el("img", (src: "media/placeholder.svg", alt: "", width: "640", height: "400"))[]
/// A terminal recording: a box the player fills, its data inline (so it
-/// plays from file://), its caption under it. The first ready one plays.
+/// plays from file://), its caption under it.
#let ready-casts = casts.filter(c => c.ready)
#let cast(c, i) = el("figure", (class: if i == 0 { "clip cast first" } else { "clip cast" }))[
#if c.ready { el("div", (class: "player", id: "cast-" + c.name, "aria-label": c.title))[] } else { placeholder }
@@ -145,14 +147,29 @@
#let player-script = {
let list = ready-casts.enumerate().map(((i, c)) => (
id: "cast-" + c.name, data: read("casts/" + c.name + ".cast"),
- cols: c.cols, rows: c.rows, autoPlay: i == 0,
+ cols: c.cols, rows: c.rows,
))
// "</" may not appear inside a script element
let data = json.encode(list, pretty: false).replace("</", "<\\/")
el("script", (src: "player/asciinema-player.min.js"))[]
- el("script")[#("for (const c of " + data + ") AsciinemaPlayer.create({data: c.data}, document.getElementById(c.id), {cols: c.cols, rows: c.rows, autoPlay: c.autoPlay, loop: true, fit: 'width'});")]
+ el("script")[#("for (const c of " + data + ") { const el = document.getElementById(c.id); el.player = AsciinemaPlayer.create({data: c.data}, el, {cols: c.cols, rows: c.rows, autoPlay: true, loop: true, fit: 'width'}); }")]
}
+/// Plays a recording while it is on screen and pauses it once it leaves.
+#let in-view-script = el("script")[#(
+ "(() => { if (!('IntersectionObserver' in window)) return;
+" +
+ " const p = el => el.player || (el.tagName === 'VIDEO' ? el : null);
+" +
+ " const io = new IntersectionObserver(es => { for (const e of es) { const r = p(e.target); if (!r) continue;
+" +
+ " if (e.isIntersecting) Promise.resolve(r.play()).catch(() => {}); else r.pause(); } }, {threshold: 0.25});
+" +
+ " for (const el of document.querySelectorAll('.clip video, .cast .player')) io.observe(el);
+" +
+ "})();"
+)]
+
#document(href("index"), title: "pardes", shell("index", "pardes")[
#el("h1", (class: "masthead"))[pardes]
#el("p", (class: "lead"))[#landing.lead]
@@ -185,6 +202,7 @@
el("link", (rel: "stylesheet", href: "player/asciinema-player.css"))[]
player-script
}
+ #in-view-script
])
#for p in pages.slice(1, -1) {