phetsims / paper-land

Build and explore multimodal web interactives with pieces of paper!
https://phetsims.github.io/paper-land/
MIT License
10 stars 1 forks source link

Interactive Display doesn't align the available area #220

Closed jessegreenberg closed 3 months ago

jessegreenberg commented 3 months ago

During a codesign session, the Interactive Display didn't line up with papers in full screen OR default modes. The interactive space was a small area in the upper left of the screen. Its not clear why this happened, lets investigate. It ocurred on a MacOS device in Chrome.

It seemed to self-resolve randomly during the session (developer tools were open when it was fixed).

jessegreenberg commented 3 months ago

@terracoda and I were able to see this on her machine.

We found a workaround:

go to Chrome -> View -> Enter Full Screen. Now the page will be in full screen (including console and everything). Now if you press Projector Mode, it should be correctly aligned.

The size of the display in projector mode was roughly related to the size of the browser window when you pressed "Projector Mode".

We aren't doing anything too fancy for full screen mode, just using the support provided by Scenery:

            if ( props.sceneryDisplay ) {
              phet.scenery.FullScreen.enterFullScreen( props.sceneryDisplay );
            }

We were not, however, able to produce the problem with a PhET sim.

jessegreenberg commented 3 months ago

Some recommendations from ChatGPT:

1. **Ensure CSS is Correct**: Make sure your CSS is correctly set up to allow the div to expand to the full screen. Use:

div {
       width: 100vw;
       height: 100vh;
       object-fit: cover; /* If you're displaying images or videos */
   }
2. **Use Fullscreen API Correctly**: Make sure you're using the Fullscreen API correctly. When you request the fullscreen on the div, ensure you're targeting the correct element. For example:

function goFullScreen() {
       const elem = document.querySelector("#yourDivId");
       if (elem.requestFullscreen) {
           elem.requestFullscreen();
       } // Add else if for vendor prefixes: mozRequestFullScreen, webkitRequestFullscreen, msRequestFullscreen
   }
3. **Adjust Styles on Fullscreen Change**: Listen for the fullscreen change event and adjust your styles accordingly. For example:

document.addEventListener("fullscreenchange", (event) => {
       if (document.fullscreenElement) {
           document.fullscreenElement.style.width = '100vw';
           document.fullscreenElement.style.height = '100vh';
       }
   });
4. **Use Viewport Units in CSS**: If not already, use viewport units (`vw`, `vh`) for width and height to ensure they cover the entire screen.
jessegreenberg commented 3 months ago

We also have this code for the full screen change. I think it is likely that innerWidth and innerHeight are not what we expect.

https://github.com/phetsims/paper-land/blob/2daf721e654e290f781ca9c687546bc0fbb730cb/client/board/PaperLandControls.js#L31-L39

This part is specific to paper playground and explains why we might not see this in a sim.

EDIT: I wonder if we need to do this BEFORE the full screen request. EDIT2: No - this patch breaks adds a black bar below the display (the whole thing is shifted up a bit)

```patch Subject: [PATCH] Indicate that items have been sorted, see https://github.com/phetsims/scenery-phet/issues/815 --- Index: client/board/PaperLandControls.js IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/client/board/PaperLandControls.js b/client/board/PaperLandControls.js --- a/client/board/PaperLandControls.js (revision b63df446842ef173dcf681027a62fe2009693a2b) +++ b/client/board/PaperLandControls.js (date 1707843551556) @@ -30,13 +30,13 @@ if ( props.sceneryDisplay ) { if ( fullScreen ) { - // remove the styling that positions the board for development - props.sceneryDisplay.domElement.classList.remove( styles.simDisplayPanel ); - props.sceneryDisplay.domElement.classList.remove( styles.boardPanel ); - - // take up the full window - props.sceneryDisplay.setWidthHeight( window.innerWidth, window.innerHeight ); - phet.paperLand.displaySizeProperty.value = new phet.dot.Dimension2( window.innerWidth, window.innerHeight ); + // // remove the styling that positions the board for development + // props.sceneryDisplay.domElement.classList.remove( styles.simDisplayPanel ); + // props.sceneryDisplay.domElement.classList.remove( styles.boardPanel ); + // + // // take up the full window + // props.sceneryDisplay.setWidthHeight( window.innerWidth, window.innerHeight ); + // phet.paperLand.displaySizeProperty.value = new phet.dot.Dimension2( window.innerWidth, window.innerHeight ); } else { const smallWidth = 640; @@ -137,6 +137,15 @@

EDIT3: Another thought is that window.innerWidth and window.innerHeight are updated async by the browser and not correct for a bit. We could add a timeout, or even better a resize observer like this:

const resizeObserver = new ResizeObserver(entries => {
  for (let entry of entries) {
    // Assuming we are observing the full-screen element
    const {width, height} = entry.contentRect;
    props.sceneryDisplay.setWidthHeight(width, height);
    phet.paperLand.displaySizeProperty.value = new phet.dot.Dimension2(width, height);
  }
});

// Start observing a target element at some point in your code
resizeObserver.observe(document.documentElement); // Or another target element

// Don't forget to disconnect the observer when it's no longer needed
jessegreenberg commented 3 months ago

A ResizeObserver was added and it works well on Windows Chrome. But I tested wiht @terracoda and it did not fix the problem.

On @terracoda's machine we noticed that occasionally, the problem does not happen. We have a theory that it happens when the browser is at an aspect ratio that is very different from the user's full screen, but we aren't sure.

jessegreenberg commented 3 months ago

With @terracoda, we found that if I remove the resizeObserver.disconnect, it aligns correctly! So lets leave it observing and wait to remove it when full screen is lost.

jessegreenberg commented 3 months ago

OK! The resize observer is added when we enter full screen, and removed when we exit.

Closing.