Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Screen.contentArea and canvas seems to get out of sync when resizing window #2435

Closed
mattjennings opened this issue Jul 27, 2022 · 7 comments · Fixed by #2439
Closed

Screen.contentArea and canvas seems to get out of sync when resizing window #2435

mattjennings opened this issue Jul 27, 2022 · 7 comments · Fixed by #2439
Labels
bug This issue describes undesirable, incorrect, or unexpected behavior

Comments

@mattjennings
Copy link
Contributor

I might be misunderstanding how to use Screen.contentArea, but it seems that when using a display mode of FitScreenAndFill either the bounds are incorrect or the canvas does not draw positions properly after the window is resized.

Here's a video of the codesandbox repro below. When I refresh the page, the positions are correct.

CleanShot.2022-07-27.at.16.48.50.mp4

Steps to Reproduce

repro: https://codesandbox.io/s/excalibur-fitscreenandfill-bug-epeb2u?file=/src/index.js

Red box is anchored to top/left of contentArea, while green box represents the entire bounds of contentArea. If you resize the window, they drift from where they should be. If you refresh the page they are in the proper spot, and notice the logged coordinates of the red box are the same before/after the refresh.

If I'm doing anything incorrect please let me know!

Expected Result

Setting an object's position to bounds of Screen.contentArea should stay consistent after window resize

Actual Result

Positions drift after resize, but are in expected position after refresh using same window dimensions

Environment

  • browsers and versions: Chrome 103, also seeing same behaviour on FireFox and Safari
  • operating system: macOS 12.4
  • Excalibur versions: 0.27
  • I am using a device with devicePixelRatio of 2 (macbook pro)

Current Workaround

@eonarheim
Copy link
Member

@mattjennings Thanks for the bug!

Definitely feels like a bug, I share your expectations 👍

@eonarheim eonarheim added the bug This issue describes undesirable, incorrect, or unexpected behavior label Jul 28, 2022
@eonarheim
Copy link
Member

I have a workaround for this example, it positions the camera in the center of the screen. This may not work in all situations... but not totally sure.

engine.onPostUpdate = () => {
  engine.currentScene.camera.pos = engine.screen.center;
}

I think the core issue with contentArea the *AndFill style display modes is that the resolution changes dynamically (more world space pixels), but the camera position does not adjust with it. I think the fix will involve adjusting camera position or the default graphics context transform?

@eonarheim
Copy link
Member

Oh I just realized that contentArea is in screen space which is a potentially confusing aspect. Actors in world space still drift unexpectedly, but this will draw the contentArea in world space at least.

bounds.on("preupdate", () => {
  // calculate safe area in world space
  const topLeft = engine.screen.screenToWorldCoordinates(ex.vec(engine.screen.contentArea.left, engine.screen.contentArea.top));
  const bottomRight = engine.screen.screenToWorldCoordinates(ex.vec(engine.screen.contentArea.right, engine.screen.contentArea.bottom));
  bounds.pos = topLeft;
  bounds.graphics.current[0].graphic.width = bottomRight.x - topLeft.x;
  bounds.graphics.current[0].graphic.height = bottomRight.y - topLeft.y;
  bounds.graphics.recalculateBounds();
});

@eonarheim
Copy link
Member

Sorry for all the spam! Would you expect that the top left of the content area would always correspond to (0, 0) in world space? I feel like that should be the right thing to expect (currently not the case in excalibur)

image

@mattjennings
Copy link
Contributor Author

I think that is what I would expect, but this is the first time I've ever worked with a dynamic resolution so I'm not sure if that's the correct expectation 😅. If that's also what you would expect though, then I think that would be the proper change. I may have also been thrown off by the contentArea being in the screen space like you said, but I think your code snippet there might do the trick. I'll give it a shot!

In the end, I was looking for a way to consistently anchor to any side of the "safe" area following resize, and that if I refresh the page at those dimensions, it'll be the same placement. I think what confused me the most was the difference in positions when resizing and then refreshing.

@eonarheim
Copy link
Member

@mattjennings I think I've got this fixed up in the PR, some small code changes but it should produce the desired effect once merged.

The contentArea is in screen space, so to draw those bounds I switched the bounds actor to coordPlane: ex.CoordPlane.Screen. Now the origin should always be the top left of the green bounds 🚀
content-area

var engine = new ex.Engine({
  width: 400,
  height: 400,
  displayMode: ex.DisplayMode.FitScreenAndFill
});


var box = new ex.Actor({
  pos: ex.vec(50, 50),
  width: 64,
  height: 64,
  color: ex.Color.Red,
  anchor: ex.vec(0, 0)
});

var bounds = new ex.Actor({
  color: ex.Color.Green,
  height: 1,
  width: 1,
  coordPlane: ex.CoordPlane.Screen,
  anchor: ex.vec(0, 0)
});

engine.add(bounds);
engine.add(box);


bounds.on("preupdate", () => {
  bounds.graphics.current[0].graphic.width = engine.screen.contentArea.width;
  bounds.graphics.current[0].graphic.height = engine.screen.contentArea.height;
});

engine.start();

eonarheim added a commit that referenced this issue Aug 6, 2022
… regardless of resolution (#2439)

Closes #2435

## Changes:

- With the `*AndFill` style display modes, basing the camera postion on the `Screen.contentArea` will keep things drawing consistently
- Sets the origin for `CoordPlan.Screen` space graphics to the top left of the `Screen.contentArea`
- Added visual test
@mattjennings
Copy link
Contributor Author

@eonarheim this is awesome! Thanks a ton, this looks like a fantastic solution. Great job!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue describes undesirable, incorrect, or unexpected behavior
Projects
None yet
2 participants