[Three.js] Chapter 8 Fullscreen and resizing full screen and resizing

08.Fullscreen and resizing full screen and resizing

introduce

Our canvas currently has a fixed resolution 800x600. Your project doesn't necessarily require WebGL to fill the entire screen, but if you want an immersive experience, filling the entire screen might be better.
First, we want the canvas to take up all the available screen space. Then, we need to make sure that it still adapts to the viewport when the user resizes the window. Finally, we need a way to provide the user with a full-screen experience.

set up

Getting started covers what we've done in the previous lesson. Our cube is in the center and we can drag and drop to move the camera.

fit viewport

To make the canvas change completely according to the viewport, then you can't sizesuse a fixed number in the variable, use window.innerWidthand window.innerHeight:

// ...

// Sizes
const sizes = {
    
    
    width: window.innerWidth,
    height: window.innerHeight
}

// ...


You can see that the canvas now has the width and height of the viewport. Unfortunately, there is a white margin and a scrollbar (try scrolling if you don't see any).
The reason is that browsers have default styles for things like important headings <h1>, underlined links <a/>, spaces between paragraphs, and padding on the page. There are many ways to go about this, which may depend on the rest of your site's pages. If you have content from other pages, try not to pollute the global styles while doing this.
We'll keep the styles and use CSS to fix the position of the canvas.
Our HTML loads src/style.cssthe file:

<link rel="stylesheet" href="./style.css">

You can write standard CSS as usual and the page will automatically reload.
A good first thing to do is to use a wildcard to remove the styles of the and *on all elements :marginpadding

*
{
    
    
    margin: 0;
    padding: 0;
}

Then, we can pin the canvas to the top left corner, using its class webglto select it:

.webgl
{
    
    
    position: fixed;
    top: 0;
    left: 0;
}

widthYou don't need to specify either on the canvas heightbecause Three.js renderer.setSize(...)already handles that when you call the method.
As you drag and drop, you may have noticed a blue outline on it. This mostly happens on recent versions of Chrome. To fix this, we can simply .webgladd outline: none:

.webgl
{
    
    
    position: fixed;
    top: 0;
    left: 0;
    outline: none;
}

If you want to remove any kind of scrolling, even on touch screens, you can add on html, :bodyoverflow: hidden

html,
body
{
    
    
    overflow: hidden;
}


Unfortunately, if the window is resized, the canvas won't change with it.
We need to handle the renderer so that it adapts to window resizing .

Handle resizing

To resize the canvas, we first need to know when the window is resized. To do this, events can be listened to on the window resize.
Add a listener that will be triggered automatically after resizethe browser's variables are changed:sizes

window.addEventListener('resize', () =>
{
    
    
    console.log('window has been resized')
})

Now that we fire a function when the window is resized, we need to update a few things in our code.
First, we must update sizesthe variable:

window.addEventListener('resize', () =>
{
    
    
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight
})

Second, we must update the aspect ratio cameraby changing its aspectproperties:

window.addEventListener('resize', () =>
{
    
    
    // ...

    // Update camera
    camera.aspect = sizes.width / sizes.height
})

When you change the camera properties, aspectyou also need to camera.updateProjectionMatrix()update the projection matrix with it. We'll talk about matrices later:

window.addEventListener('resize', () =>
{
    
    
    // ...

    camera.updateProjectionMatrix()
})

Finally, we must update renderer. the update renderer which will automatically update the width and height of the canvas :

window.addEventListener('resize', () =>
{
    
    
    // ...

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
})

Full code:

window.addEventListener('resize', () =>
{
    
    
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
})

You can resize the window as needed and the canvas should cover the viewport without any scrollbars or overflow.

Processing Pixel Ratio

As we develop, some people may see a blurry rendering and artifacts with edges shaped like stairs (called aliasing), but not everyone will. If you're having issues like this, it's because your screen has a pixel ratio greater than 1 .
The pixel ratio corresponds to how many physical pixels are on the screen in one pixel unit of the software part.

some history

A few years ago, all screens had the same pixel ratio 1and everything was fine. But when you look closely at your screen, you can see those pixels, which limit the precision of images and the fineness of fonts.
The company that has done the most in this regard is Apple. Apple saw an opportunity and started making 2screens with Retina pixel ratios. Now, many builders are doing this, and you can see screens with higher pixel ratios.
While this is a good thing for image quality, the pixel ratio 2means there are 4x more pixels to render as well. Pixel ratio 3means 9 times more pixels to render.
guess what? The highest pixel ratios are usually found on devices with the smallest screens—mobile devices.
Including frame rate.

Processing Pixel Ratio

window.devicePixelRatioGet the screen pixel ratio you can use, just call renderer.setPixelRatio(...)update renderer's pixel ratio after getting the pixel ratio.
You may want to simply send the device pixel ratio to the method, but you will end up with performance issues on high pixel ratio devices.
The larger pixel ratio 2is mainly for marketing. Your eyes can barely see the difference between 2and 3, but it can create performance issues and drain the battery faster. An optimization that can be done is to limit the pixel ratio to 2. To do this, you can use Math.min():

renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))


There are techniques to notify us as developers when the pixel ratio changes, but it only concerns users who have multiple screens with different pixel ratios, and they usually resize windows when switching from one screen to another. That's why we also simply add this method to resizethe callback:

window.addEventListener('resize', () =>
{
    
    
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})

handle full screen

Now that our canvas takes up all the available space with the correct pixel ratio, it's time to add support for fullscreen.
First, we need to decide what action will trigger fullscreen mode. It could be an HTML button, but for our example we'll use a double click to trigger fullscreen.
When the double-click happens, we toggle fullscreen - meaning that if the window is not fullscreen, the double-click will enable fullscreen mode, and if the window is already fullscreen, the double-click will exit fullscreen mode.
First, we need to listen to the double-click event, which we can dblclickachieve through the event:

window.addEventListener('dblclick', () =>
{
    
    
    console.log('double click')
})

This event works in most modern browsers except Chrome Android: https://developer.mozilla.org/docs/Web/API/Element/dblclick_event Now
that we have our double click event, we need three things:

  • A way to know if it's already fullscreen
  • How to enter full screen mode
  • A way to exit fullscreen mode

To know if we are already in fullscreen mode we can use document.fullscreenElement:

window.addEventListener('dblclick', () =>
{
    
    
    if(!document.fullscreenElement)
    {
    
    
        console.log('go fullscreen')
    }
    else
    {
    
    
        console.log('leave fullscreen')
    }
})

A method to request full screen is associated with the element. This is because you can choose what goes full screen. It can be the whole page, any DOM element or <canvas>.
We will use <canvas>and call equestFullscreen()its method:

window.addEventListener('dblclick', () =>
{
    
    
    if(!document.fullscreenElement)
    {
    
    
        canvas.requestFullscreen()
    }
    else
    {
    
    
        console.log('leave fullscreen')
    }
})

The method of exiting full screen mode can be directly in document:

window.addEventListener('dblclick', () =>
{
    
    
    if(!document.fullscreenElement)
    {
    
    
        canvas.requestFullscreen()
    }
    else
    {
    
    
        document.exitFullscreen()
    }
})

You can test the results by double-clicking anywhere to toggle full-screen mode. Unfortunately, this doesn't work for Safari
Safaribrowsers that are taking their time to support officially simple features like fullscreen, we need to use prefixed versions to make it work for document.fullscreenElement, canvas.requestFullscreenand document.exitFullscreen:

window.addEventListener('dblclick', () =>
{
    
    
    const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement

    if(!fullscreenElement)
    {
    
    
        if(canvas.requestFullscreen)
        {
    
    
            canvas.requestFullscreen()
        }
        else if(canvas.webkitRequestFullscreen)
        {
    
    
            canvas.webkitRequestFullscreen()
        }
    }
    else
    {
    
    
        if(document.exitFullscreen)
        {
    
    
            document.exitFullscreen()
        }
        else if(document.webkitExitFullscreen)
        {
    
    
            document.webkitExitFullscreen()
        }
    }
})

Everything should work fine on all modern browsers, compatible with all browsers.

Guess you like

Origin blog.csdn.net/m0_68324632/article/details/130790467