Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions src/components/flash.astro
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
---
import FullscreenButton from "./fullscreen-button.astro";

interface Props {
gamePath: string;
}

const { gamePath } = Astro.props;
---

<div class="text-center">
<div id="flash-player-wrap" data-path={gamePath} class="flex items-center justify-center p-6 min-h-[calc(100vh-100px)] box-border">
<div id="flash-container" class="text-center">
<div id="flash-player-wrap" data-path={gamePath} class="flex items-center justify-center p-6 min-h-[calc(100vh-100px)] box-border">
<div class="flash-loading">Loading game...</div>
</div>
<div class="flex justify-center pt-2">
<FullscreenButton targetId="flash-container" />
</div>
</div>

<style>
/* ponytail: fullscreen the outer container (game + button) so exit stays visible */
:global(#flash-container:fullscreen) {
padding: 0;
min-height: 100vh;
background: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
</style>

<script src="/ruffle/ruffle.js" is:inline></script>
<script is:inline>
(function () {
Expand Down Expand Up @@ -55,9 +73,11 @@ const { gamePath } = Astro.props;
function resize() {
var vw = window.innerWidth;
var vh = window.innerHeight;
var pad = 32;
var headerOffset = 120;
var maxW = Math.min(vw - pad * 2, 1040);
// ponytail: in fullscreen drop the page chrome offsets and width cap so the game fills the screen
var isFs = !!document.fullscreenElement && document.fullscreenElement.id === "flash-container";
var pad = isFs ? 0 : 32;
var headerOffset = isFs ? 0 : 120;
var maxW = isFs ? vw : Math.min(vw - pad * 2, 1040);
var maxH = vh - headerOffset - pad * 2;
var w = maxW;
var h = w / ASPECT_RATIO;
Expand Down
57 changes: 57 additions & 0 deletions src/components/fullscreen-button.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
interface Props {
targetId: string;
}

const { targetId } = Astro.props;
---

<button
type="button"
data-fullscreen-for={targetId}
aria-live="polite"
class="rounded-lg border border-gray-300 bg-white px-4 py-1.5 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
>
⛶ Full screen
</button>

<script is:inline>
(function () {
function updateLabels() {
document.querySelectorAll("[data-fullscreen-for]").forEach(function (btn) {
var active =
!!document.fullscreenElement &&
document.fullscreenElement.id === btn.getAttribute("data-fullscreen-for");
btn.textContent = active ? "✕ Exit full screen" : "⛶ Full screen";
btn.setAttribute("aria-pressed", active ? "true" : "false");
});
}
document.addEventListener("click", function (e) {
var btn = e.target && e.target.closest ? e.target.closest("[data-fullscreen-for]") : null;
if (!btn) return;
var target = document.getElementById(btn.getAttribute("data-fullscreen-for") || "");
if (!target) return;
if (document.fullscreenElement) {
document.exitFullscreen().catch(function (err) { console.warn("Exit fullscreen failed:", err); });
} else if (target.requestFullscreen) {
target.requestFullscreen().catch(function (err) { console.warn("Enter fullscreen failed:", err); });
}
});
// ponytail: re-dispatch resize so existing game resize handlers adapt
document.addEventListener("fullscreenchange", function () {
updateLabels();
window.dispatchEvent(new Event("resize"));
});
updateLabels();
})();
</script>

<style>
:global(#flash-container:fullscreen, #run3-container:fullscreen, #webtris-container:fullscreen) {
background: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
</style>
56 changes: 48 additions & 8 deletions src/pages/games/[slug].astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
import Layout from "../../layout/layout.astro";
import Flash from "../../components/flash.astro";
import FullscreenButton from "../../components/fullscreen-button.astro";
import { gamesMap } from "../../data/game-seo";

export async function getStaticPaths() {
Expand All @@ -18,8 +19,13 @@ const seo = gamesMap[slug];
) : slug === "run-3" ? (
<>
<base href="/games/run3/" />
<div id="run3-wrapper" class="text-center h-[96vh] w-full">
<div id="openfl-content" class="bg-black w-full h-full" />
<div id="run3-container">
<div id="run3-wrapper" class="text-center h-[96vh] w-full">
<div id="openfl-content" class="bg-black w-full h-full" />
</div>
<div class="flex justify-center pt-2">
<FullscreenButton targetId="run3-container" />
</div>
</div>
<script src="/games/run3/Run3.js" is:inline></script>
<script data-astro-rerun is:inline>
Expand Down Expand Up @@ -48,15 +54,49 @@ const seo = gamesMap[slug];
</script>
</>
) : slug === "webtris" ? (
<div class="flex justify-center items-center min-h-[80vh] bg-[#010101]">
<iframe
src="https://theoneand33.github.io/webtris/"
class="w-full max-w-[90vw] h-[80vh] border-0"
title="Webtris"
/>
<div id="webtris-container">
<div id="webtris-wrapper" class="flex justify-center items-center min-h-[80vh] bg-[#010101]">
<iframe
src="https://theoneand33.github.io/webtris/"
class="w-full max-w-[90vw] h-[80vh] border-0"
title="Webtris"
/>
</div>
<div class="flex justify-center pt-2">
<FullscreenButton targetId="webtris-container" />
</div>
</div>
) : (
<p class="p-6 text-center text-gray-600">Game not available.</p>
)
}
</Layout>

<style>
/* ponytail: in fullscreen fill the screen, keep game aspect ratio */
:global(#run3-container:fullscreen) {
height: 100vh;
}
:global(#run3-container:fullscreen #run3-wrapper) {
height: 100%;
}
:global(#run3-container:fullscreen #openfl-content) {
display: flex;
align-items: center;
justify-content: center;
}
:global(#run3-container:fullscreen canvas) {
width: min(100vw, 133.33vh);
height: auto;
}
:global(#webtris-container:fullscreen) {
min-height: 100vh;
}
:global(#webtris-container:fullscreen #webtris-wrapper) {
min-height: 100vh;
}
:global(#webtris-container:fullscreen iframe) {
max-width: 100vw;
height: 100vh;
}
</style>
Loading