You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**SerializedSprite, SerializedSceneComposition**: JSON-safe versions of scene composer types
72
+
-**SerializedSprite, SerializedSceneComposition**: JSON-safe versions of scene composer types. `SceneComposition` carries an optional `resolution?: { width: number; height: number }` field (defaults to 1920×1080 when absent) persisted in `project.ide.json`.
73
73
-**ImageMapComposition**: Container for a clickable imagemap — ground image, optional hover overlay, and an array of hotspots. Persisted in `ProjectSettings.imagemapCompositions` (keyed by id) and saved to `project.ide.json`.
74
74
-**ImageMapHotspot**: A single clickable region with `x`, `y`, `width`, `height`, an `ImageMapActionType` (`'jump' | 'call'`), and a target label
75
75
-**SerializedImageMapComposition**: JSON-safe version of an imagemap composition
@@ -131,6 +131,7 @@ API keys are stored encrypted via Electron's `safeStorage` at `userData/api-keys
131
131
-**UI rendering**: Functional components with hooks only, no class components
132
132
-**Modals/overlays**: Rendered via `createPortal()`; all modals use `useModalAccessibility` hook for focus trap, Escape key close, and focus restore
133
133
-**Styling**: Tailwind CSS utility classes; dark mode via `class` strategy
134
+
-**Copy-to-clipboard**: Always use `components/CopyButton.tsx`. Props: `text` (string to copy), `label` (default `"Copy to Clipboard"`), `size` (`'xs'` for code-preview headers / list rows, `'sm'` default, `'md'` for primary action buttons). Idle state: clipboard icon + label. After click: green bg, checkmark, "Copied!" for 2 s. Never write per-component clipboard state or `alert()` feedback.
134
135
-**Path alias**: `@/*` maps to project root in imports (tsconfig)
135
136
-**Block = file**: Each `.rpy` file maps 1:1 to a Block on the canvas; the first label becomes the block title
136
137
-**Accessibility**: Icon-only buttons must have `aria-label`; modals must have `role="dialog"`, `aria-modal`, and `aria-labelledby`
@@ -181,6 +182,15 @@ Users can create custom code snippets (persisted in `AppSettings.userSnippets`):
181
182
182
183
The app integrates AI APIs (Google Gemini via `@google/genai`, with optional OpenAI and Anthropic support via dynamic imports) for generating story content. API keys are encrypted at rest using Electron's `safeStorage`. The generator UI lives in `components/AIGenerator.tsx`.
183
184
185
+
## Scene Composer
186
+
187
+
`components/SceneComposer.tsx` provides a visual layout editor for positioning backgrounds and sprites:
188
+
- Drag-and-drop images from the Image Assets panel onto the stage; drag sprites to reposition
189
+
- Supports per-sprite zoom, flip, rotate, alpha, and blur controls; layer reordering via drag in the layer list
190
+
-**Configurable canvas resolution**: toolbar dropdown offers presets (1920×1080, 1280×720, 1024×768, 800×600) plus a "Custom…" option revealing W×H number inputs. Resolution persists in `SceneComposition.resolution` and is saved to `project.ide.json`. Defaults to 1920×1080 when absent (backwards compatible).
191
+
- Generates Ren'Py `scene`/`show` code in the Code Preview panel; exports a composited PNG via canvas
0 commit comments