cypher

help with device orientation and canvas resize

Recommended Posts

Hello everyone, I'm trying to make a resizable canvas following this guides I found in this forum https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html. I'm sure this topic has been discussed plenty of times and I have spent some time searching for some info I could use but with no luck (most of the replies make use of window.innerWidth/innerHeight). The thing is that It seems ok when displayed on a desktop or a mobile device in portrait mode, but when I change to landscape and reload the page nothing is shown on the canvas. As far as I know when it rotates, width becomes greater than height and coordinate system does not change at all, so I don't know what I'm missing :( (something related to mobile resolutions and ppi maybe?)

I'm fairly new to html/css/js and I'm certain that the issue is related to my poor knowledge with some concepts. Here is the code anyway, any help or directions would be very much appreciated.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=no"/>
    <title>My PIXI App</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.6/pixi.min.js"></script>
    </script>
</head>
<body>
</body>
</html>
* {
  padding: 0;
  margin: 0;
}

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

body {
  background-color: lightslategrey;
}

canvas {
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
}
const width = 512;
const height = 512;

const appOptions = {  
  width: width,
  height: height,
  resolution: window.devicePixelRatio,
  roundPixels: true,
  transparent: false,
  backgroundColor: 0x555555,
};

const app = new PIXI.Application(appOptions);
document.body.appendChild(app.view);

coolResize();
app.ticker.add(coolResize);

drawSquare();
drawSquare(app.view.width / 2 - 25, app.view.height / 2 - 25);


function coolResize() {  
  const multiplier = app.renderer.options.resolution || 1;
  const clientWidth = Math.floor(app.view.clientWidth * multiplier);
  const clientHeight = Math.floor(app.view.clientHeight * multiplier);

  if (app.view.width !== clientWidth || app.view.height !== clientHeight) {
    app.view.width = clientWidth;
    app.view.height = clientHeight;    
        
    return true;
  }

  return false;
}

function drawSquare(x = 0, y = 0) {
  const graphics = new PIXI.Graphics();
  graphics.lineStyle(2, 0xFF00FF, 1);
  graphics.beginFill(0xFF00BB, 0.25);
  graphics.drawRoundedRect(x, y, 50, 50, 10);
  graphics.endFill();

  app.stage.addChild(graphics);
}

I've created a fiddle just in case it could be of any help:

https://jsfiddle.net/pmyzLk35/

 

Thank you so much and I'm sorry for wasting your time.

PS. Btw I don't know why should I resize first and then add the resize function to the ticker, shouldn't adding to the app.ticker be enough? I tried it but does not lead to the same result. I'll take a look to the docs later I guess.

Share this post


Link to post
Share on other sites

Dont change it directly please, use "app.renderer.resize".

Also, there's "app.screen" which is rectangle in CSS pixels.

"app.view" is canvas, and its width/height are in real pixels.

app.renderer.resize(window.innerWidth, window.innerHeight); //that'll do!
console.log(app.screen);
console.log(app.view.width, app.view.height);

CSS pixels are used inside the stage, so drawSquare should use "app.screen" too.

Also I recommend to look up how "WebGLRenderer.resize" works and what is "autoResize". It just changes CSS when you call "resize". If you want , you can remove "100%" from css and turn on autoResize.

https://github.com/pixijs/pixi.js/blob/dev/src/core/renderers/SystemRenderer.js#L225

https://github.com/pixijs/pixi.js/blob/dev/src/core/renderers/webgl/WebGLRenderer.js#L374

Share this post


Link to post
Share on other sites

Thank you for replying ivan.popelyshev. I use the solution you mention here for the past year and it works for my use case, but like greggman from https://webglfundamentals.org mentions there are some use cases where using clientWidth and clientHeight is advantageous.

I would like to explore the other option cypher's question is asking about. Here is another greggman article that shows how he does it: https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html

Chad mentioned in 2016 that he uses it:

 

If you see it Chad could you please paste some code snippet showing how you handle resizing in Pixi?

If anybody else uses clientWidth and clientHeight + css for resizing please share your experience. Thank you in advance!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.