zzwx

hitArea upon devicePixelRatio change

Recommended Posts

Hello,

Before creating any bug reports, I just wanted to hear if anyone experienced a similar issue.

Basically, I'm trying to make my scene react properly not only to the change of screen dimensions, but also to resolution change, device pixel ratio. To do so, I'm using Opera (I believe it is Chrome behind the scenes), and I click Device Toolbar to activate other predefined screen sizes.

My problem is that if I simply resize the view, hitArea seems to be following properly. However as soon as I flip from mobile to standard or backwards, essentially changing the devicePixelRatio, it gets misplaced. I can hunt with the mouse and clicking, where the hitArea appears, and basically it is somewhere in the middle from left top corner to the object location. I tried to issue "onResize" upon each size change in which I would create a completely new Rectangle for hitArea like this:

this.button.hitArea = new PIXI.Rectangle(-Dimensions.CELL_HEIGHT, -Dimensions.CELL_HEIGHT, Dimensions.CELL_HEIGHT*2, Dimensions.CELL_HEIGHT*2)

However this seems to be not moving the area to corresponding location where container is drawn. I know that CELL_HEIGHT is properly updated before this, basically becoming a portion of a (renderer.view.height / renderer.resolution).

Again, if I just initiate on my mobile device, or Refresh the browser, the whole application works correctly until I change devicesPixelRatio.

If anyone hears this, and has any ideas as to how to fix my problem, please reply.

I'm using the latest, "pixi.js": "5.2.4"

 

 

Share this post


Link to post
Share on other sites

I'm confused now completely. I've been setting  renderer.resolution = window.devicePixelRatio upon window resize. And used (renderer.view.height / renderer.resolution) to calculate my proper view dimensions.

Now if I completely remove renderer.resolution = window.devicePixelRatio line, the hitArea starts working as intended and everything else renders as if I did nothing.

Share this post


Link to post
Share on other sites

Use "renderer.screen" its in CSS coords (independent from resolution)

Make sure that you correctly resize canvas , if you passed (800,600,2) in renderer, it should be (1600,1200) for renderer view (canvas) , and (800,600) in CSS, as well as in "renderer.screen"

I dont recommend to change resolution in window resize event, it works but there are downsides like different settings for Text and some other elements.

Theoretically, nothing should be changed in stage if you change resolution, it should just works. 

hitArea is part of interaction , InteractionManager uses it to calculate relative coords, you can try debug it

Another thing is that every person who tries to use resolution fails first time. There's always something you dont take into account. Even if I gave you a hour-length lecture about that, you still wouldnt make it right first time.

Without debugging its impossible , and you didnt even mention CSS properties in canvas  (look in pixi AbastractRenderer how it does resize() in case of autoDensity) - means you should actually try debug the code, and maybe make a minimal demo that doesnt work for you.

Edited by ivan.popelyshev

Share this post


Link to post
Share on other sites

Thank you for hints Ivan!

My problem got resolved as soon as I realized that along with renderer resolution, interaction resolution also needs to be updated.

Indeed, it's an exciting learning curve!

I'll also try to use what you suggested, renderer.screen instead of renderer.view (which I believe renderer.width / height addresses to).

Share this post


Link to post
Share on other sites

I guess I'll sum it up as this. Just for the record.



let onResize = (event: UIEvent) => {
  // Don't do this because you won't be doing renderer.width / renderer.resolution 
  // and you will cause other issues
  // if (window.devicePixelRatio != renderer.resolution) {
  // 	renderer.resolution = window.devicePixelRatio
  // 	renderer.plugins.interaction.resolution = window.devicePixelRatio
  // }
  renderer.resize(window.innerWidth, window.innerHeight)
  // Renderer's size depends on renderer.resolution automatically
  app.onResize()
}

// Base your calculations on renderer.screen rather than
// renderer.width / renderer.resolution
getViewportSize(renderer: PIXI.Renderer): PIXI.Point {
  return new PIXI.Point(renderer.screen.width,
			renderer.screen.height)
}

When interaction is based on renderer.screen as well as all rendering, there is no need to change any resolutions.

Does this sound about right?

 

Share this post


Link to post
Share on other sites

I guess I need to mention that if everything is based on renderer.screen, pixel density will not be representing actual device, so when switching from Device to Native and back, the picture will be either crisp or blurry. However during tests like this, it's not that vital, because you are actually simply testing proper interaction rather than rendering.

Edited by zzwx

Share this post


Link to post
Share on other sites

yep, it should work. 

In theory, that "if" you are using should work. If you have a demo that shows its wrong - please share.

btw, i usually put everything in setInterval(1000), and not in window resize event. Just checking if size was changed every second - that should prevent throttling when user actively resizes window

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.