shots: feature rotate, per-language frame fallback, layout-aware capture selectors
This commit is contained in:
parent
2e1c7cdc3c
commit
61b5fa0623
15 changed files with 355 additions and 17 deletions
|
|
@ -167,6 +167,10 @@ export interface ShotsConfig {
|
|||
copy: string;
|
||||
/** Raw frames: <frames>/<languageId>/<phone|tablet>/<name>.png */
|
||||
frames: string;
|
||||
/** true: every language needs its own frames (<frames>/<lang>/...). Default false: a language with copy but no frames
|
||||
* folder uses the default language's frames (play.defaultLanguage, else the first language); `shots check` / `render`
|
||||
* say so as an info line. */
|
||||
perLanguageFrames?: boolean;
|
||||
/** Output: <out>/<languageId>/<size>/NN.png and feature/1024x500.png */
|
||||
out: string;
|
||||
/** Optional logo image for the hero scene and the feature graphic. */
|
||||
|
|
@ -183,6 +187,9 @@ export interface ShotsConfig {
|
|||
* bottom edge on purpose (shots check then allows it). `scale` (0.5-1.5, default 1) multiplies the phone's width
|
||||
* (still clamped to the canvas with 'contain'). */
|
||||
feature?: { frame: string; palette?: string | Palette; fit?: 'contain' | 'bleed'; scale?: number;
|
||||
/** Degrees added to the phone's tilt (layout "bleed": the frame image is turned), like a scene frame's `rotate`: -90 stands a
|
||||
* landscape game frame upright in a phone lying on its side. Default 0. */
|
||||
rotate?: number;
|
||||
/** layout "bleed": the name on the feature graphic when there is no logo (default app.name). */
|
||||
title?: string;
|
||||
/** Photo background for the feature graphic (path relative to the config, or { image, overlay }); wins over the
|
||||
|
|
@ -207,7 +214,16 @@ export interface ShotsConfig {
|
|||
}
|
||||
|
||||
/** One raw frame. Web: `path` (+ query). Simulator / emulator: `url` deep link and / or `args` / `extras`. */
|
||||
/** Web capture: a selector, candidates tried in order, or per layout { phone, tablet, any } (own list first). Prefer data
|
||||
* attributes (`[data-shot="shop-row"]`); `text=Shop` and `role=button[name="Shop"]` work as fallbacks. */
|
||||
export type ShotSelector = string | string[] | { phone?: string | string[]; tablet?: string | string[]; any?: string | string[] };
|
||||
|
||||
export interface ShotSpec {
|
||||
/** Web: wait (up to the waitFor timeout) until one of these matches, before waitFor; a miss names the selector and the size. */
|
||||
waitSelector?: ShotSelector;
|
||||
/** Web: element(s) to click after waitSelector, in order (a list of selectors is ONE click with fallbacks; use
|
||||
* [{...}, {...}] objects for several clicks). */
|
||||
click?: ShotSelector | ShotSelector[];
|
||||
/** Web: URL path after baseUrl, "{lang}" replaced. */
|
||||
path?: string;
|
||||
/** ios-sim / android-emu: deep link opened after launch, e.g. "mygame://shot/{shot}?lang={lang}". */
|
||||
|
|
@ -1259,6 +1275,7 @@ export function validateConfig(c: unknown): string[] {
|
|||
if (s.feature !== undefined) {
|
||||
if (!s.feature || typeof s.feature.frame !== 'string' || !s.feature.frame) e.push('shots.feature.frame: a frame name');
|
||||
if (s.feature?.fit !== undefined && s.feature.fit !== 'contain' && s.feature.fit !== 'bleed') e.push("shots.feature.fit: 'contain' | 'bleed'");
|
||||
if (s.feature?.rotate !== undefined && !(typeof s.feature.rotate === 'number' && Math.abs(s.feature.rotate) <= 360)) e.push('shots.feature.rotate: a number of degrees from -360 to 360');
|
||||
if (s.feature?.scale !== undefined && !(typeof s.feature.scale === 'number' && s.feature.scale >= 0.5 && s.feature.scale <= 1.5)) e.push('shots.feature.scale: a number from 0.5 to 1.5');
|
||||
e.push(...featureBackgroundIssues(s.feature?.background));
|
||||
if (s.feature?.palette !== undefined) e.push(...paletteIssues(s.feature.palette, 'shots.feature.palette'));
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue