fake-screencast – Screenshots → simulierte Bildschirmaufnahme
Vervollständige einen Screenshot-Walkthrough so, dass er wie eine echte Bildschirmaufnahme wirkt: ein permanenter Browser-Chrome mit einer URL-Leiste, die sich pro Seite ändert, einem benutzerdefinierten Cursor, der entlang eines Bézier-Pfades zu jedem Klickziel easet und beim Klick kräuselt, Seitennavigation als harter Schnitt (URL-Pfad ändert sich), ein In-Seiten-Filter als kurze Überblendung (URL-Query ändert sich), sanftes Scrollen, ein langsamer Ken-Burns-Zoom auf das finale Element und eine konstante Drift, damit es nie wie eine Diaschau aussieht. TSX-first: steuerbar, wieder-renderbar, wiederverwendbar über mehrere Videos.
Dies ist eine Beat-Building-Technik innerhalb von make-tsx (Schritt 2). Verwende make-tsx für die timeline.json-/render-/bake-Mechanik und die Sync-to-Words-Prinzipien; verwende vidtsx-2d-generator für die Low-Level-Regeln, die eine Remotion-Datei vor Abstürzen bewahren (nur frame-basiert, monotones interpolate, Easing.bezier, kein useState/useEffect). Der Shot, den du hier schreibst, folgt diesen Regeln.
Wann dieses Tool richtig ist (Entscheidungstor)
- Gefälschter Screencast (dieses Skill) – Du hast oder kannst Screenshots der Zustände aufnehmen und möchtest einen kontrollierten Walkthrough (Cursor-Pfad, Hervorhebung, Zoom, Timing synchron zur Erzählung). Dies ist P4 „echte UI für Konfiguration“, nur simuliert. Am besten einsetzbar, wenn es im Walkthrough um wo die Dinge sind/die Schritte geht, nicht um rohe Geschwindigkeit.
- Echte Bildschirmaufnahme – Nur wenn es um echten Beweis geht: echte Latenz, ein Live-Ergebnis, das erscheint, etwas, das du nicht glaubwürdig fälschen kannst. Hinterlasse einen klar markierten
pending_recording-Platzhalter, bis er eintrifft (siehemake-tsx). - Einzelne statische Seite klonen – Wenn es eine Seite ohne Navigation/Cursor ist (z. B. eine Preisseite, die du nur hervorheben/scrollen möchtest), verwende direkt
WebBrowserFrameauslib/browser.tsx. Greife nicht zur Screencast-Mechanik.
Schritt 1 – Screenshots besorgen (Benutzer fragen)
Teile dem Benutzer die genaue Shot-Liste mit, die du benötigst (ein Screenshot pro Seite oder Zustand, auf den der Cursor landet), und warte dann auf ihn. Anforderungen:
- Eingeloggt / echte Daten, die tatsächliche Produkt-UI, aufgenommen in einer konsistenten Fenstergröße (idealerweise ~1920 breit).
- Einer pro Zustand, einschließlich Zwischenzustände: Eine ungefilterte Liste UND ihr gefiltertes Ergebnis zählen als zwei Screenshots (die Überblendung verkauft das „Suche angewendet“).
- Für ein echtes Scrollen durch eine lange Seite benötigst du einen hohen Capture (gesamte Seite, unter dem Falz) – ein Einzel-Viewport-Screenshot kann nicht wirklich scrollen (du kannst nur ein paar Pixel Drift vortäuschen). Sage dies und bitte um den hohen Capture, wenn der Beat es benötigt.
- Frage nach fehlenden Ansichten mit Namen (z. B. „die Modelle-Liste gefiltert auf X“, „die Einstellungsseite nach dem Umschalten von Y“).
Speichere sie in media/library/images/<service>/ mit klaren Namen (account-home.png, workers-ai.png, models-all.png, models-flux.png). Referenziere sie in einer Seite als library/images/<service>/<name>.png (das ist der staticFile-relative Pfad, den die Komponente erwartet).
Schritt 2 – Die Library-API (remotion/src/lib/screencast.tsx)
<Screencast pages cursor clicks box glow favicon appearAt />. Koordinaten sind BRÜCHE, damit sie jede Größenänderung überleben:
- Cursor
x/yund Klick-Kräuselungen → VIEWPORT-BRUCH (0..1 des Seitenbereichs unter der URL-Leiste). - Zoom
fx/fy→ BILD-BRUCH (Transformationsursprung des Push).
import { Screencast, ScreencastPage, CursorKey } from '../../lib/screencast';
const PAGES: ScreencastPage[] = [
{ img: 'library/images/svc/home.png', url: 'app.svc.com/…/home', tabTitle: 'Home | Svc', enterAt: 0 },
{ img: 'library/images/svc/list.png', url: 'app.svc.com/…/items', tabTitle: 'Items | Svc', enterAt: 130, transition: 'cut' }, // Navigation → harter Schnitt + neuer Pfad
{ img: 'library/images/svc/filtered.png', url: 'app.svc.com/…/items?q=x', tabTitle: 'Items | Svc', enterAt: 262, transition: 'crossfade', transitionFrames: 5, // In-Seiten-Filter → Überblendung + gleicher Pfad + Query
drift: 0.01, zoom: { from: 1.0, to: 1.4, fx: 0.32, fy: 0.52, range: [266, 289] } }, // Ken-Burns auf die Auszahlungskarte
];
const CURSOR: CursorKey[] = [ // {frame, x, y} in Viewport-Brüchen; pro Segment ge-eased
{ frame: 0, x: 0.60, y: 0.42 }, { frame: 128, x: 0.09, y: 0.68 }, /* … */ { frame: 294, x: 0.36, y: 0.52 },
];
const CLICKS = [130, 206, 255]; // Frames, bei denen eine Kräuselung ausgelöst wird (platziere sie am Ankunft-Keyframe)
export const compositionConfig = { id: 'SvcRecording', durationInSeconds: 10.0, fps: 30, width: 1920, height: 1080 };
const SvcRecording = () => <Screencast pages={PAGES} cursor={CURSOR} clicks={CLICKS} />;
export default SvcRecording;
Seitenfelder: img, url, tabTitle, enterAt (erforderlich); transition?: 'cut'|'crossfade' (Standard cut), transitionFrames? (Standard 5), scroll?: {to, range:[a,b], from?} (Bild-px translateY), zoom?: {from,to,fx,fy,range:[a,b]}, drift? (Standard 0.02 — der konstante langsame „lebendig“-Push). Screencast-Props: box? (Standard {x:60,y:63,w:1800,h:954}), glow?, appearAt?, favicon? (Standard Cloudflare-Wolke — übergib dein eigenes für andere Dienste).
Schritt 3 – Timing + Koordinaten
- Frame 0 = der
master_in_sdes Shots. Für einen Erzählungs-Hinweis beitSekunden:frame = round((t − master_in_s) × fps). Durchsucheedited-transcript.jsonnach dem genauen Wortanfang/-ende (ms). Setze den Klick / dasenterAtder Seite ein paar Frames vor dem Wort, damit das Ergebnis auf dem Wort landet; beende einen Ken-Burnszoom.rangeauf dem Auszahlungswort. - Finde einen Klickziel-Bruch aus dem Screenshot: Pixelposition des Elements ÷ Bildbreite/-höhe ≈ der Viewport-Bruch (das Bild füllt den Seitenbereich, oben ausgerichtet, an Breite angepasst). Setze dort das Ankunft-Keyframe des Cursors und füge den Klick-Frame ~2f nach der Ankunft hinzu. Dann rendere und schaue (Schritt 4) – justiere den Bruch, bis der Zeiger auf dem Element sitzt.
- Ordne jede Seite/Cursor-Bewegung ihrem Hinweis zu: Dashboard-Haltepunkt auf der Einleitungszeile → Cursor easet zu einem Sidebar-Element und klickt, während dieses Element genannt wird → nächste Seite erscheint → Zoom zur Auszahlung, während das Auszahlungswort gesprochen wird.
Fallstricke (jeder hat ein Render zum Finden gekostet)
- Null-Höhe enthaltender Block.
WebBrowserFrameumschließt Kinder in einemtransformierten Div, das zum enthaltenden Block für absolute Nachkommen wird und auf Höhe 0 kollabiert. Seitenebenen benötigen daher explizite Regionsabmessungen (width/heightaus der Box), nichtinset:0– die Lib macht das bereits; behalte es bei, wenn du es erweiterst. - Navigation vs. Filter ist der Realismus-Verrat. Ein Seitenwechsel = harter Schnitt + anderer URL-Pfad. Eine In-Seiten-Suche/Filter = kurze Überblendung + gleicher Pfad (Query angehängt). Diese zu verwechseln wirkt gefälscht.
- Einzel-Viewport-Screenshots können nicht scrollen – täusche „Lebendigkeit“ stattdessen mit
drift+ einem Ken-Burnszoomvor. Verwende ein echtesscrollnur, wenn du einen hohen Capture hast. - Render
--scale=1für die Vorschau (1080p, korrekt fürbake.py); erneut rendern mit--scale=2für das 4K60-Finale. - Der Cursor-Hotspot (die Spitze) befindet sich nahe der oberen linken Ecke des Zeiger-SVGs; die Lib korrigiert dies. Wenn ein Zeiger ein paar Pixel daneben aussieht, justiere den Zielbruch, nicht das SVG.
Schritt 4 – Verifizieren, dann zurück zu make-tsx
- Rendere + Screenshot bei JEDEM Hinweis (niemals ein Standbild):
node remotion/scripts/render-all.mjs --scale=1 <Id>, dann extrahiere Frames mit ffmpeg beim Cursor-auf-Ziel-Frame, jedem Klick-Frame, dem Seitenwechsel-Frame und dem Zoom-Auszahlungs-Frame. Bestätige, dass der Zeiger auf dem Element landet, URLs korrekt wechseln und der Zoom das Richtige einrahmt. Iteriere die Brüche/Frames und rendere erneut. - Folge dann
make-tsxfür den Rest: aktualisieretimeline.json(tausche/ändere die Zeitspanne, entferne jeglichenpending_recording-Hinweis),python tools/bake.py, und überprüfe die zusammengesetzten Frames des Shots über dem echten Master beim Beat und an beiden Grenzen. - Wenn du die Komponente verbesserst (pro Seite Favicons, echten getippten Text in einem Feld, eine Untertitel-Ebene), fördere sie zurück in
lib/screencast.tsx, damit zukünftige Videos davon profitieren.
Die kanonische Form – kopiere diese Choreographie
Die Bewegung, die wie eine echte Bildschirmaufnahme wirkt, über ~4 erfasste Seiten und ~10s:
- Halte auf der Landeseite, während die Erzählung sie aufbaut (ein Beat von
drift, niemals ein eingefrorener Frame). - Cursor easet zu einem Sidebar-Element und klickt auf das Wort, das es nennt – der Klick landet auf dem Nomen, nicht davor.
- Harter Schnitt zu dieser Seite, URL-Pfad ändert sich. Dies ist eine Navigation.
- Tippe einen Filter → kurze Überblendung, gleicher Pfad mit angehängter Query. Dies ist keine Navigation, und es als eine solche zu rendern, ist der größte Verrat.
- Ken-Burns-Zoom auf die Auszahlung genau dann, wenn das Auszahlungswort gesprochen wird.
Lies remotion/src/lib/screencast.tsx, bevor du eines baust – es ist die Engine, und seine Props sind die Dokumentation für jede Bewegung oben. Das Seiten-Array, die Cursor-Keyframes, die URL und der Zoom pro Seite sind dort alle typisiert.