fix(web): cap canvas via Window resize_constraints (real surface fix) #100
@@ -6,43 +6,28 @@
|
||||
<title>Ferrous Solitaire</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { background: #000; overflow: hidden; }
|
||||
/* #bevy-wrap fills the viewport but is capped to the GPU's real
|
||||
MAX_TEXTURE_SIZE via an inline max-width/height set before init
|
||||
(see the clamp script below). fit_canvas_to_parent sizes the wgpu
|
||||
surface to this element, so capping it keeps the surface within
|
||||
WebGL2's per-dimension limit. Centered so 2048-limited devices
|
||||
letterbox symmetrically. */
|
||||
#bevy-wrap {
|
||||
width: 100vw; height: 100vh; margin: 0 auto;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
html, body { height: 100%; background: #000; overflow: hidden; }
|
||||
/* Cap the canvas at WebGL2's 2048 max texture dimension (this mirrors
|
||||
the Window `resize_constraints` in solitaire_web/src/lib.rs — winit
|
||||
applies that constraint as the canvas's own max-width/max-height).
|
||||
On wasm Bevy creates the device with downlevel_webgl2_defaults()
|
||||
whose max_texture_dimension_2d is a fixed 2048, so a larger surface
|
||||
(e.g. a 4K display at 150% scale → a 2560x1440 logical viewport)
|
||||
makes Surface::configure panic. `max-*` directly on the canvas keeps
|
||||
the surface ≤ 2048 regardless of how fit_canvas_to_parent resolves
|
||||
its 100% width; `margin: 0 auto` centres the letterbox horizontally. */
|
||||
#bevy-canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 2048px;
|
||||
max-height: 2048px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
#bevy-canvas { display: block; width: 100%; height: 100%; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="bevy-wrap"><canvas id="bevy-canvas"></canvas></div>
|
||||
<script>
|
||||
// Clamp the Bevy canvas's backing buffer to 2048px *before* the wasm
|
||||
// initialises. `fit_canvas_to_parent` sizes the wgpu surface to
|
||||
// #bevy-wrap, and on wasm Bevy creates the device with
|
||||
// `Limits::downlevel_webgl2_defaults()` (forced by
|
||||
// `WgpuSettingsPriority::WebGL2` in solitaire_web/src/lib.rs), whose
|
||||
// `max_texture_dimension_2d` is a fixed **2048** — independent of the
|
||||
// GPU's real MAX_TEXTURE_SIZE (which is why querying the hardware limit
|
||||
// doesn't help: a 4K/integrated GPU reports e.g. 8192 but wgpu still
|
||||
// caps the surface at 2048). A surface wider/taller than 2048 makes
|
||||
// Surface::configure panic and kill the WASM thread on the first frame
|
||||
// — e.g. a 3840x2160 display at 150% scale gives a 2560x1440 logical
|
||||
// viewport → a 2560-wide surface. So the cap is the constant 2048.
|
||||
// Keep in sync with the wgpu limit selected in lib.rs.
|
||||
(function clampCanvasToWebgl2Limit() {
|
||||
var MAX = 2048; // wgpu downlevel_webgl2_defaults().max_texture_dimension_2d
|
||||
var wrap = document.getElementById("bevy-wrap");
|
||||
wrap.style.maxWidth = MAX + "px";
|
||||
wrap.style.maxHeight = MAX + "px";
|
||||
})();
|
||||
</script>
|
||||
<canvas id="bevy-canvas"></canvas>
|
||||
<script type="module">
|
||||
import init from "/web/pkg/canvas.js";
|
||||
// solitaire_wasm.js provides SolitaireGame with the full debug / automation
|
||||
|
||||
@@ -13,7 +13,7 @@ use bevy::asset::AssetMetaCheck;
|
||||
use bevy::prelude::*;
|
||||
use bevy::render::RenderPlugin;
|
||||
use bevy::render::settings::{RenderCreation, WgpuSettings, WgpuSettingsPriority};
|
||||
use bevy::window::{Window, WindowPlugin, WindowResolution};
|
||||
use bevy::window::{Window, WindowPlugin, WindowResizeConstraints, WindowResolution};
|
||||
use solitaire_data::LocalOnlyProvider;
|
||||
use solitaire_engine::CoreGamePlugin;
|
||||
use wasm_bindgen::prelude::*;
|
||||
@@ -42,6 +42,19 @@ pub fn start() {
|
||||
// resize event and killing the WASM thread.
|
||||
resolution: WindowResolution::default()
|
||||
.with_scale_factor_override(1.0),
|
||||
// Cap the surface at WebGL2's max texture dimension (2048).
|
||||
// On wasm Bevy creates the device with
|
||||
// `Limits::downlevel_webgl2_defaults()` (max_texture_dimension_2d
|
||||
// = 2048), so a larger surface — e.g. a 4K display at 150% scale
|
||||
// gives a 2560x1440 logical viewport — makes Surface::configure
|
||||
// panic on the first frame. winit maps this constraint to the
|
||||
// canvas's `max-width`/`max-height` style, so the surface can
|
||||
// never exceed it. Viewports wider/taller than 2048 letterbox.
|
||||
resize_constraints: WindowResizeConstraints {
|
||||
max_width: 2048.0,
|
||||
max_height: 2048.0,
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
|
||||
Reference in New Issue
Block a user