typstage

0.2.0

Animated HTML talks and a PDF handout from one source.

GeoGebra#

Die Konstruktion baut GeoGebra, die Dramaturgie kommt aus den Folien. Auf jedem Schritt können Aufträge liegen: Werte setzen, Objekte zeigen oder verbergen, Farben ändern, den Ausschnitt verschieben, eine Bewegung anstoßen.

Schnellstart#

geogebra() setzt das Applet auf die Folie; die Befehle stehen im selben Folienrumpf und geben selbst nichts aus.

#import "@preview/typstage:0.2.0": *

#presentation(
  slide([Ferngesteuert], {
    geogebra(app: "classic", perspective: "G", height: 240pt,
             link: "https://www.geogebra.org/calculator")
    ggb-run("a=1", "f(x)=a*x^2")
    ggb-set((a: 3), at: 2)
  }),
)

Die Parabel steht von Anfang an da; auf Schritt 2 wird a auf 3 gesetzt und sie zieht sich zusammen.

at ist bei allen Befehlen ein Schrittwähler wie bei anim: 2, "1-2", "2,4", "-2". Vorgabe ist "1-" – die meisten Aufträge richten die Konstruktion beim Betreten der Folie ein. Der Applet-Rahmen selbst verbraucht keinen Schritt.

Welches Applet gemeint ist#

Ein einzelnes Applet finden die Befehle von selbst, gleich ob sie im Quelltext darüber oder darunter stehen. Zwei Applets auf einer Folie brauchen Namen, die Befehle brauchen target. Der Name ist eine Zeichenkette oder eine Marke:

#geogebra(<links>, height: 200pt)
#geogebra(<rechts>, height: 200pt)
#ggb-run("A=(0,0)", target: <links>)
#ggb-run("B=(1,1)", target: "rechts")

Fehlt target bei mehreren Applets – oder steht gar keines auf der Folie –, bricht der Bau ab:

error: panicked with: typstage: 2 applets on this slide
(links, rechts) — say which one is meant, e.g. target: "links".

Die Konstruktion aufbauen#

ggb-run nimmt beliebig viele GeoGebra-Befehle und gibt sie einzeln an evalCommand weiter. Die Reihenfolge zählt: was gebraucht wird, muss vorher entstanden sein.

#ggb-run(at: "1-",
         "k: x^2+y^2=4", "t=Slider(0,6.283,0.01)",
         "P=(2cos(t),2sin(t))", "s=Segment((0,0),P)")
Achtung
GeoGebras Skriptbefehle – SetColor, SetValue, SetVisibleInView und Verwandte – nimmt evalCommand nicht an; in ggb-run blieben sie wirkungslos. Dafür gibt es ggb-set, ggb-style, ggb-show und ggb-hide: sie greifen zur JavaScript-Schnittstelle, die das kann.

Was GeoGebra ablehnt, landet in der Konsole des Browsers.

Beim Betreten der Folie und beim Zurückblättern beginnt das Applet von vorn. Befehle müssen deshalb wiederholbar sein, und die Farbe gehört gleich auf "1-" – sonst vergibt GeoGebra beim Neuaufbau die nächste Farbe seiner Palette.

#ggb-run("a=1", "f(x)=a*x^2", at: "1-")
#ggb-style("f", at: "1-", color: dark, thickness: 3)
Hinweis
Eine .ggb-Datei lässt sich nicht einbetten. Die Konstruktion entsteht mit ggb-run – oder sie kommt über material von GeoGebra: geogebra(material: "abc123xy").

Werte, Aussehen, Ausschnitt#

ggb-set nimmt ein Wörterbuch aus Objektname und Wert, ggb-show und ggb-hide beliebig viele Objektnamen. Üblich ist: alles zu Beginn aufbauen, verbergen, und Schritt für Schritt zeigen.

#ggb-hide("P", "s", "t", at: "1-")
#ggb-show("P", "s", at: 2)
#ggb-set((a: 3), at: 2)
#ggb-set((a: -2, b: 0.5), at: 3)

Aussehen#

ggb-style nimmt die Objektnamen und dazu, was sich ändern soll. Was nicht genannt wird, bleibt, wie es ist.

AngabeWirkung
colorFarbe – eine Typst-Farbe, keine GeoGebra-Farbe
thicknessStrichstärke
line-styleStrichart als Zahl (durchgezogen, gestrichelt, gepunktet …)
fillingFüllung, 0 bis 1
point-sizePunktgröße
traceSpur an oder aus
labelBeschriftung sichtbar oder nicht
label-modeArt der Beschriftung als Zahl (Name, Wert, Beschriftung …)
fixedgegen Verschieben festhalten
captioneigene Beschriftung
layerEbene, also was vor was liegt
positionOrt als (x, y)

color nimmt eine Typst-Farbe: die Konstruktion trägt damit die Farben der Folien statt GeoGebras Palette.

#ggb-style("P", at: 2, color: accent, point-size: 6)
#ggb-style("s", at: 2, color: dark, thickness: 3)
#ggb-style("d", at: 3, color: accent, filling: 0.18, thickness: 4)

Ausschnitt#

ggb-view setzt den sichtbaren Bereich sowie Gitter und Achsen. x und y wirken nur zusammen – beide sind Paare aus kleinstem und größtem Wert.

#ggb-view(at: 2, x: (-3, 3), y: (-3, 3), grid: false)
#ggb-view(at: 3, axes: false)

Ohne ggb-view ergibt sich der Ausschnitt aus width und height: ein breiter Kasten zeigt mehr x-Bereich.

Bewegung#

ggb-animate startet GeoGebras eigene Animation. Sie läuft ohne Ende hin und her, bis die Folie verlassen wird – richtig für einen umlaufenden Punkt oder einen Schieberegler. trace schaltet die Spur ein, speed regelt das Tempo, playing: false hält an.

#ggb-animate("t", at: 3, speed: 1.2, trace: ("P",))

ggb-tween geht einmal von A nach B und bleibt dort. Der Browser zählt den Wert Bild für Bild hoch; ein Objekt, das von ihm abhängt, wächst mit – so zeichnet sich die Konstruktion selbst. from gibt den Anfangswert, duration die Dauer in Millisekunden, easing den Verlauf ("ease-in-out" oder "linear"). Danach sitzt der Wert auf seinem Ziel: wer zurückblättert, sieht die fertige Zeichnung.

#ggb-run("t_1=0", "s=Segment(A,(4*t_1,0))", at: "1-")
#ggb-tween("t_1", at: 2, to: 1, duration: 700)
Achtung
ggb-tween braucht eine Schrittnummer, keinen Bereich: at: 2, nicht at: "2-". Sonst bricht der Bau mit „ggb-tween() needs a step number“ ab. Und auf Schritt 1 wird nichts gezeichnet: beim Betreten der Folie setzt die Laufzeit Tweens sofort auf ihren Zielwert. Schritt 1 ist zum Aufbauen da.

Auf Papier#

Im PDF gibt es kein Applet. Ohne weitere Angabe steht dort ein beschrifteter Platzhalter in der Größe des Rahmens; link setzt darunter einen anklickbaren Weg zum lebenden Applet.

#geogebra(height: 90pt, link: "https://www.geogebra.org/calculator")

Besser ist eine eigene Zeichnung. fallback nimmt beliebigen Inhalt – ein Bild, eine Tabelle, und vor allem eine Zeichnung mit CeTZ:

#geogebra(height: 120pt, link: "https://www.geogebra.org/calculator",
  fallback: cetz.canvas(length: 0.8cm, {
    import cetz.draw: *
    line((-2.6, 0), (2.6, 0), stroke: luma(70%))
    line((0, -0.4), (0, 2.6), stroke: luma(70%))
    line(..range(0, 45).map(i => (-2.2 + i * 0.1, 0.5 * calc.pow(-2.2 + i * 0.1, 2))),
         stroke: dark + 1.6pt)
  }))

fallback und link wirken nur im PDF; im Browser steht dort das Applet.

Aussehen des Applets#

Vorgabe ist seamless: true: das Applet trägt keinen eigenen Rahmen und seine Zeichenfläche bekommt die Farbe der Folie. background bestimmt diese Farbe. auto nimmt das Papierweiß der Präsentation – auf einer getönten Folie ist es zu ändern.

#geogebra(height: 240pt, background: rgb("#f4f1ea"))
#geogebra(height: 240pt, seamless: false)   // mit GeoGebras eigenem Rahmen
Achtung
Der Ausschnitt lässt sich mit der Hand nicht verschieben. Wer im Vortrag danebengreift, schöbe sonst die ganze Ebene weg. pan: true gibt Verschieben und Zoomen zurück; Punkte und Schieber lassen sich in beiden Fällen ziehen.

font-size ist die Schrift des Applets, gezählt in Punkten der Folie; sie wächst also mit der Folie mit. Vorgabe ist 17.

Achtung
GeoGebra rastet die Schriftgröße in Stufen ein: benachbarte Werte fallen oft auf dieselbe Höhe zusammen. Ein Zwischenwert gibt nicht unbedingt einen Zwischenschritt.
#geogebra(height: 240pt, font-size: 22)      // größere Achsenzahlen
#geogebra(height: 240pt, pan: true)          // Ausschnitt von Hand

grid und axes lassen GeoGebras Vorgabe stehen, solange sie auto sind, und erzwingen sonst das eine oder andere. perspective: "G" zeigt nur die Grafik-Ansicht, app wählt die GeoGebra-App (Vorgabe "classic"), language die Sprache der Oberfläche, animation-button blendet GeoGebras Abspielknopf ein.

Größe#

width und height geben die Größe in den Maßen der Folie, nicht in Bildschirmpunkten. Welcher Ausschnitt zu sehen ist, hängt am Bereich: den setzt das Applet einmal aus den Punktmaßen des Kastens, danach gilt ggb-view. Eine Größenänderung lässt ihn stehen.

Tipp
Zwei Applets nebeneinander stehen am besten in einem grid, jedes mit width: 100% und eigener Höhe.

Aus der Sprecheransicht#

Das Sprecherfenster führt von jedem Applet eine eigene Kopie. m schaltet den Zeiger vom Stift auf die Einbettung um; von da an bedient der Vortragende das lebende Applet, und die Kopie auf der Leinwand zieht nach.

Hinüber geht nur, was eine Hand bewegt: ein Punkt als seine Koordinaten, ein Schieber als sein Wert – was daraus folgt, rechnet die andere Kopie selbst aus. Wird etwas angelegt, gelöscht oder umbenannt, geht die ganze Konstruktion hinüber. Eine Animation läuft auf beiden Seiten und schickt nichts.

Achtung
Ein Schrittwechsel setzt beide Kopien zurück und spielt die Aufträge der Folie erneut. Eine Änderung von Hand lebt also nur so lange wie der Schritt. Soll eine Position bleiben, gehört sie mit ggb-set ins Deck.

Die Tastatur#

Ein Klick gibt dem Applet den Fokus: von da an landet jede Taste darin, bis auf die Tasten des Vortrags, die aus dem Rahmen zurückgereicht werden (siehe „Ein Rahmen, der den Fokus hat„).

Tipp
Was sich nicht bewegen soll, gehört festgehalten. ggb-style("A", "B",
fixed: true)
nagelt die Punkte fest, die eine Konstruktion nur aufspannen. Sonst greift eine Hand im Vortrag leicht den Falschen – beim Satz des Thales etwa den Durchmesser statt des Punktes auf dem Halbkreis.

Point(k) ist ein Punkt auf der Bahn, den eine Hand nehmen kann; Point(k,
0.3)
liegt fest und lässt sich nicht ziehen. Wo er starten soll, sagt position:.

examples/geogebra-sprecher.typ zeigt beides: Thales mit einem Punkt auf dem Halbkreis, und eine Parabel mit zwei Schiebern.

Wessen Applet das ist#

Dieses Paket schickt GeoGebra nicht mit. Es setzt einen Rahmen auf die Folie; was darin läuft, holt der Browser von codebase, ab Werk https://www.geogebra.org/apps/. Daraus folgen drei Dinge:

  1. Ohne Netz bleibt der Rahmen leer. Wer offline vorführt, legt GeoGebras Dateien daneben und zeigt mit codebase darauf.
  2. Das Applet steht unter GeoGebras Bedingungen, nicht unter der MIT-Lizenz dieses Pakets. Für eine kommerzielle Verwendung sind sie zu lesen.
  3. Der Browser des Zuschauers spricht mit geogebra.org. Wo das nicht erwünscht ist – eine Klasse ohne Netz, ein Vortrag hinter einer Firewall, eine Datenschutzauflage –, lässt sich das mit codebase umlenken.