feat(web,engine): portrait-orientation scene images for mobile full-bleed
Thread orientation (portrait|landscape) from client through API, engine, and image gen. Portrait devices render 1024x1792 (9:16) full-bleed scenes; desktop/landscape keeps 1792x1024 (16:9). Adds cover-aware click→image coordinate mapping, session-locked orientation, a shared coerceOrientation helper, and a choices overflow cap in portrait. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,23 @@ export type BeatChoiceEffect =
|
||||
| { kind: "advance-beat"; targetBeatId: string }
|
||||
| { kind: "change-scene"; nextSceneSeed: string };
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────
|
||||
// Orientation — session-wide image aspect, locked at session start.
|
||||
// "landscape" → 16:9 (1792×1024), the default for desktop / mobile-landscape.
|
||||
// "portrait" → 9:16 (1024×1792), painted for mobile users holding the phone
|
||||
// upright so the scene fills the screen instead of letterboxing a widescreen
|
||||
// image. CSS object-fit then adapts the 9:16 frame to the exact device size.
|
||||
// ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
export type Orientation = "portrait" | "landscape";
|
||||
|
||||
/** Normalize an untrusted orientation value (from a request body, or a
|
||||
* persisted session that predates the field) to a valid Orientation.
|
||||
* Anything other than "portrait" falls back to "landscape" (back-compat). */
|
||||
export function coerceOrientation(value: unknown): Orientation {
|
||||
return value === "portrait" ? "portrait" : "landscape";
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────
|
||||
// Scene — one background image + a graph of beats.
|
||||
// The Director emits an entire Scene per call; the player navigates
|
||||
@@ -75,6 +92,12 @@ export type Scene = {
|
||||
* Runware URL — the client renders both forms transparently.
|
||||
*/
|
||||
imageUrl?: string;
|
||||
/**
|
||||
* Orientation this scene's image was painted in. Mirrors the session's
|
||||
* locked orientation; recorded per-scene so the client can pick the right
|
||||
* intrinsic dimensions / object-fit even across legacy or mixed history.
|
||||
*/
|
||||
orientation?: Orientation;
|
||||
};
|
||||
|
||||
export type SceneExit =
|
||||
@@ -251,6 +274,12 @@ export type Session = {
|
||||
* payload small for /api/scene round-trips.
|
||||
*/
|
||||
styleReferenceImage?: string;
|
||||
/**
|
||||
* Session-wide image orientation, locked at session start from the client's
|
||||
* device + orientation and carried on every /api/scene call so all scenes
|
||||
* share one aspect ratio. Absent → "landscape" (back-compat).
|
||||
*/
|
||||
orientation?: Orientation;
|
||||
};
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────
|
||||
@@ -337,6 +366,12 @@ export type StartRequest = {
|
||||
* drops `config.tts` so the engine skips all server-side TTS work.
|
||||
*/
|
||||
clientTts?: boolean;
|
||||
/**
|
||||
* Device orientation chosen at session start. "portrait" makes the engine
|
||||
* paint 9:16 vertical scene images (mobile, held upright); "landscape"
|
||||
* (default) keeps 16:9 widescreen. Locked for the whole session.
|
||||
*/
|
||||
orientation?: Orientation;
|
||||
};
|
||||
|
||||
// /api/parse-style-image — vision LLM extracts a textual painting-style
|
||||
|
||||
Reference in New Issue
Block a user