简体   繁体   中英

HTML5 canvas height and width 100% distorts the game animation

I am not sure, how i can be more specific, but i am putting my best effort to explain it.I am trying to understand, what should i be looking for to be more specific, so this is all i have got at this moment.

I was exploring HTML5 JavaScript games, and I noticed, that making the canvas height and width 100% distorts the animation within. a simple example that i got from here . If i change the canvas size to 100% (in the example I have provided) it breaks the animation of the game(for example the asteroid).

I would like to know, which property of HTML5 is responsible for this behaviour and what should I be looking for to get the HTML5 animation fit the complete screen size?

EDIT
I tried to run cordova to build the game to native platform,but the 1st problem i am encountering is that the canvas was not fitting the screen size. (that's why i wanted it to completely fit the browser screen, but i see a complete misfit when a canvas made for the browser screen is rendered to the native using cordova).
I explored phaser, about how they are solving this problem, and found this game which is using something called a ScalingManager .
So, my questions are
1. What is scaling a Game?
2. How is the scaling-manager of phaser working
3. without using the scaling manager why will a game not fit the moile screen size even though the canvas height and width are properly mentioned?
4. is there a small experment (without using any phaser or similar javascript game framework) that i can do to understand the need for scaling with simple HTML5 javasctipt and cordova?

A canvas has two distinct sizes:

  • the size of the element on the page
  • the size in pixel of the canvas

To avoid distortion and get a pixel-perfect graphic you need to ensure they end up equal... for example:

function redraw() {
    canvas.width = canvas.offsetWidth;
    canvas.height = canvas.offsetHeight;
    ...
}

For single-page HTML games where you just want to draw everything in a canvas a simple approach is:

<!DOCTYPE html>
<html>
  <head>
    <style type='text/css'>
       * {
          margin: 0;
          padding: 0;
          border: none;
       }

       body,html {
          height: 100%;
          width: 100%;
       }

    </style>
  </head>
  <body>
    <script>
        var canvas = document.createElement('canvas');
        canvas.style.position = 'absolute';
        var body = document.body;
        body.insertBefore(canvas, body.firstChild);
        var context = canvas.getContext('2d');

        var devicePixelRatio = window.devicePixelRatio || 1;
        var backingStoreRatio = context.webkitBackingStorePixelRatio
            || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio
            || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
         var ratio = devicePixelRatio / backingStoreRatio;

        redraw();
        window.addEventListener('resize', redraw, false);
        window.addEventListener('orientationchange', redraw, false);
        function redraw() {
            width = (window.innerWidth > 0 ? window.innerWidth : screen.width);
            height = (window.innerHeight > 0 ? window.innerHeight : screen.height);
            canvas.style.width = width + 'px';
            canvas.style.height = height + 'px';
            width *= ratio;
            height *= ratio;

            if (canvas.width === width && canvas.height === height) {
              return;
            }

            canvas.width = width;
            canvas.height = height;
        }
        //draw things
    </script>
  </body>
</html>

You will also need to check for changes in innerWidth / innerHeight if your app has parts in which you're just waiting for user interaction (not looping on calling redraw ) and the user instead resizes the browser window or tilts the phone/tab.

With Phaser 3, I succeeded by adding window.innerWidth and window.innerHeight to the Scale object into my config :

config: Phaser.Types.Core.GameConfig = {
type: Phaser.AUTO,
scale: {
  mode: Phaser.Scale.FIT,
  parent: 'phaser-game',
  autoCenter: Phaser.Scale.CENTER_BOTH,
  width: window.innerWidth,
  height: window.innerHeight
},
scene: [MainScene],
parent: 'gameContainer',
physics: {
  default: 'arcade',
  arcade: {
    gravity: {y: 0}
  }
}
};

For the moment I don't see any problem, it makes the trick.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM