(engine: VisualNovelEngine)
| 182 | * Capture the current game screen as a JPEG Blob |
| 183 | */ |
| 184 | export async function captureGameScreenshot (engine: VisualNovelEngine): Promise<Blob | null> { |
| 185 | const gameScreen = engine.element ().find ('[data-screen="game"]').get (0) as HTMLElement | undefined; |
| 186 | |
| 187 | if (!gameScreen || gameScreen.offsetWidth === 0) { |
| 188 | return null; |
| 189 | } |
| 190 | |
| 191 | // Ensure animations are settled before capturing the screenshot. |
| 192 | const settleAnimations = document.createElement ('style'); |
| 193 | settleAnimations.textContent = '[data-screen="game"], [data-screen="game"] *, [data-screen="game"] *::before, [data-screen="game"] *::after { animation-duration: 0s !important; animation-delay: 0s !important; transition: none !important; }'; |
| 194 | |
| 195 | try { |
| 196 | document.head.appendChild (settleAnimations); |
| 197 | |
| 198 | const { domToBlob } = await import ('modern-screenshot'); |
| 199 | |
| 200 | return await domToBlob (gameScreen, { |
| 201 | quality: 0.8, |
| 202 | type: 'image/jpeg', |
| 203 | scale: 400 / gameScreen.offsetWidth, |
| 204 | }); |
| 205 | } catch (e) { |
| 206 | engine.debug.warn ('Screenshot capture failed:', e); |
| 207 | |
| 208 | return null; |
| 209 | } finally { |
| 210 | settleAnimations.remove (); |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | function revealScreen (engine: VisualNovelEngine, screen: string): void { |
| 215 | hideScreens (engine); |
no test coverage detected