LGTM
This commit is contained in:
parent
a8165249a4
commit
a4103b0896
64 changed files with 5376 additions and 3832 deletions
|
|
@ -60,6 +60,19 @@ export interface AdScene {
|
|||
left?: AdScenePanel;
|
||||
right?: AdScenePanel;
|
||||
items?: AdSceneItem[];
|
||||
/** Optional single hero photo (URL) shown above the title. */
|
||||
image?: string;
|
||||
/** Optional [left, right] photos for split mode — used by "two streets apart" style ads. */
|
||||
images?: [string, string];
|
||||
/** Optional caption shown under the image for attribution / context. */
|
||||
imageCaption?: string;
|
||||
/**
|
||||
* If true, render the scene with a transparent background so the dashboard
|
||||
* stays visible behind. Useful for hooks where you want a floating kicker
|
||||
* + title without occluding the live product. Defaults to false (full
|
||||
* scrim, used by the closing "title" cards).
|
||||
*/
|
||||
transparent?: boolean;
|
||||
}
|
||||
|
||||
/** A point on screen, resolved at runtime to viewport pixels. */
|
||||
|
|
@ -140,7 +153,19 @@ export type Activity =
|
|||
/** Fade the ad overlay away. */
|
||||
| { kind: 'hideAdScene'; durationMs: number }
|
||||
/** Fade away the opening vignette. */
|
||||
| { kind: 'clearVignette'; durationMs: number };
|
||||
| { kind: 'clearVignette'; durationMs: number }
|
||||
/**
|
||||
* Smoothly scroll the closest scrollable ancestor of `selector` to
|
||||
* absolute pixel `top`. Used to surface a specific filter card or to
|
||||
* scroll through the property-stats drawer after a postcode click.
|
||||
*/
|
||||
| { kind: 'scrollPane'; selector: string; top: number; durationMs: number }
|
||||
/**
|
||||
* Click the header of a collapsible filter group (e.g. "Transport",
|
||||
* "Education") so the cards beneath it become visible. Idempotent —
|
||||
* if the group is already open this is a no-op click.
|
||||
*/
|
||||
| { kind: 'openFilterGroup'; selector: string; durationMs: number };
|
||||
|
||||
/**
|
||||
* A narration cue + the activities that play alongside it.
|
||||
|
|
@ -281,12 +306,27 @@ export function viewportFor(video: VideoConfig): { width: number; height: number
|
|||
}
|
||||
|
||||
/**
|
||||
* Recorded video resolution. Equal to the CSS viewport because
|
||||
* Playwright's recordVideo writes frames at CSS pixel size regardless
|
||||
* of `deviceScaleFactor`. Kept as a separate function so future
|
||||
* supersample + post-encode flows (e.g. ffmpeg lanczos upscale) can
|
||||
* plug in here without touching verify.ts.
|
||||
* Recorded video resolution. Equal to the CSS viewport.
|
||||
*
|
||||
* Playwright's recordVideo captures the page at its CSS-pixel surface, so
|
||||
* passing a size larger than the viewport just letterboxes the content
|
||||
* into the top-left of an empty frame — not a true high-DPR raster.
|
||||
* Final-resolution upscale (e.g. mobile 540x960 → 1080x1920) is done in
|
||||
* render.sh's ffmpeg pass with `scale=...:flags=lanczos`, which gives a
|
||||
* sharp upscale because Chromium rasterises internally at DPR=captureScale.
|
||||
*/
|
||||
export function recordedSizeFor(video: VideoConfig): { width: number; height: number } {
|
||||
return viewportFor(video);
|
||||
}
|
||||
|
||||
/**
|
||||
* The final mp4's resolution (after the lanczos upscale pass in render.sh).
|
||||
* Storyboards drive their on-screen typography from CSS viewport sizes, but
|
||||
* social platforms care about the file resolution — so we expose a
|
||||
* separate getter for the published dimensions.
|
||||
*/
|
||||
export function publishedSizeFor(video: VideoConfig): { width: number; height: number } {
|
||||
const viewport = viewportFor(video);
|
||||
const scale = Math.max(1, Math.round(video.captureScale));
|
||||
return { width: viewport.width * scale, height: viewport.height * scale };
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue