Phaser画布宽高获取异常求助:为何无法获取style中尺寸
Hey there! Let's break down why you're struggling to get the correct canvas dimensions and how to fix this for your Phaser project.
Why This Happens
The core problem boils down to timing and how DOM styles are accessed:
- Style vs. Computed Dimensions: When you use
element.style.height, you're only pulling inline styles (set directly via thestyleattribute or JavaScript). If your canvas's dimensions come from external CSS or a stylesheet,element.stylewon't reflect those values—even ifconsole.logshowscssTextlater, that’s likely after styles have finished applying post-render. - DOM/Style Loading Timing: Your initial code is probably running before the browser finishes applying CSS to the canvas, or before Phaser fully initializes and sizes the canvas. When you click the element later, the DOM is fully rendered, styles are active, so jQuery’s
height()(which fetches computed dimensions) works as expected.
Solutions
Here are the most reliable ways to get accurate canvas dimensions:
1. Use Computed DOM Dimensions (Best for External CSS)
Skip relying on style properties and use methods that grab the actual rendered size of the canvas:
- jQuery’s
outerHeight()/outerWidth(): These return the computed size including padding and border (useinnerHeight()/innerWidth()if you don’t want padding):const canvasWidth = $('canvas').outerWidth(); const canvasHeight = $('canvas').outerHeight(); - Native JS
getBoundingClientRect(): This is the most precise way to get the element’s rendered size and position:const canvas = document.querySelector('canvas'); const rect = canvas.getBoundingClientRect(); const canvasWidth = rect.width; const canvasHeight = rect.height; - Native JS
offsetHeight/offsetWidth: These return the element’s total height/width including padding, border, and scrollbars (if any):const canvasHeight = document.querySelector('canvas').offsetHeight;
2. Leverage Phaser’s Built-in Properties
Since you’re using Phaser, the game instance already tracks canvas dimensions—no need to query the DOM directly!
- For fixed-size setups:
const game = new Phaser.Game({ type: Phaser.CANVAS, width: 800, height: 600, scene: { preload, create, update } }); // Access config-defined dimensions const gameWidth = game.config.width; const gameHeight = game.config.height; - For responsive setups (using Phaser’s Scale Manager):
// Run this in your scene's create() method (after scaling is applied) create() { const scaledWidth = this.scale.width; const scaledHeight = this.scale.height; // Use these values for your array }
3. Ensure Code Runs After DOM/Styles Are Ready
Make sure your dimension-fetching code executes after the browser finishes rendering the canvas and applying styles:
- If using jQuery, wrap your code in
$(document).ready():$(document).ready(() => { // Fetch canvas dimensions here const canvasHeight = $('canvas').height(); }); - Use Phaser’s scene lifecycle hooks: Run your dimension logic in the
create()method of your Phaser scene—it fires after the game fully initializes the canvas and applies any scaling.
Quick Debugging Test
To confirm it’s a timing issue, add a small delay before fetching dimensions (not for production, but great for testing):
setTimeout(() => { console.log('Delayed height:', $('canvas').height()); console.log('Delayed style height:', $('canvas')[0].style.height); }, 1000);
You’ll see the correct values here, proving your initial code ran too early.
内容的提问来源于stack exchange,提问作者Kvasir




