08. Pantalla completa y cambio de tamaño pantalla completa y cambio de tamaño
introducir
Nuestro lienzo actualmente tiene una resolución fija 800x600
. Su proyecto no requiere necesariamente WebGL para llenar toda la pantalla, pero si desea una experiencia inmersiva, llenar toda la pantalla podría ser mejor.
Primero, queremos que el lienzo ocupe todo el espacio disponible en la pantalla. Luego, debemos asegurarnos de que aún se adapte a la ventana gráfica cuando el usuario cambie el tamaño de la ventana. Finalmente, necesitamos una forma de proporcionar al usuario una experiencia de pantalla completa.
configuración
Primeros pasos cubre lo que hemos hecho en la lección anterior. Nuestro cubo está en el centro y podemos arrastrar y soltar para mover la cámara.
ajuste ventana gráfica
Para hacer que el lienzo cambie completamente de acuerdo con la ventana gráfica, no puede sizes
usar un número fijo en la variable, use window.innerWidth
y window.innerHeight
:
// ...
// Sizes
const sizes = {
width: window.innerWidth,
height: window.innerHeight
}
// ...
Puede ver que el lienzo ahora tiene el ancho y el alto de la ventana gráfica. Desafortunadamente, hay un margen blanco y una barra de desplazamiento (intente desplazarse si no ve ninguna).
La razón es que los navegadores tienen estilos predeterminados para cosas como encabezados importantes <h1>
, enlaces subrayados <a/>
, espacios entre párrafos y relleno en la página. Hay muchas formas de hacerlo, que pueden depender del resto de las páginas de su sitio. Si tiene contenido de otras páginas, trate de no contaminar los estilos globales mientras hace esto.
Mantendremos los estilos y usaremos CSS para corregir la posición del lienzo.
Nuestro HTML carga src/style.css
el archivo:
<link rel="stylesheet" href="./style.css">
Puede escribir CSS estándar como de costumbre y la página se recargará automáticamente.
Lo primero que debe hacer es usar un comodín para eliminar los estilos de y *
en todos los elementos :margin
padding
*
{
margin: 0;
padding: 0;
}
Luego, podemos anclar el lienzo a la esquina superior izquierda, usando su clase webgl
para seleccionarlo:
.webgl
{
position: fixed;
top: 0;
left: 0;
}
width
No necesita especificar ninguno en el lienzo height
porque Three.js renderer.setSize(...)
ya maneja eso cuando llama al método.
A medida que arrastra y suelta, es posible que haya notado un contorno azul en él. Esto sucede principalmente en versiones recientes de Chrome. Para solucionar esto, simplemente podemos .webgl
agregar outline: none
:
.webgl
{
position: fixed;
top: 0;
left: 0;
outline: none;
}
Si desea eliminar cualquier tipo de desplazamiento, incluso en las pantallas táctiles, puede agregar html
, :body
overflow: hidden
html,
body
{
overflow: hidden;
}
Desafortunadamente, si se cambia el tamaño de la ventana, el lienzo no cambiará con ella.
Necesitamos manejar el renderizador para que se adapte al cambio de tamaño de la ventana .
Manejar el cambio de tamaño
Para cambiar el tamaño del lienzo, primero debemos saber cuándo se cambia el tamaño de la ventana. Para ello, se pueden escuchar los eventos en la ventana resize
.
Agregue un oyente que se activará automáticamente después de que se cambien resize
las variables del navegador :sizes
window.addEventListener('resize', () =>
{
console.log('window has been resized')
})
Ahora que activamos una función cuando se cambia el tamaño de la ventana, necesitamos actualizar algunas cosas en nuestro código.
Primero, debemos actualizar sizes
la variable:
window.addEventListener('resize', () =>
{
// Update sizes
sizes.width = window.innerWidth
sizes.height = window.innerHeight
})
En segundo lugar, debemos actualizar la relación de aspecto camera
cambiando sus aspect
propiedades:
window.addEventListener('resize', () =>
{
// ...
// Update camera
camera.aspect = sizes.width / sizes.height
})
Cuando cambia las propiedades de la cámara, aspect
también necesita camera.updateProjectionMatrix()
actualizar la matriz de proyección con ella. Hablaremos de matrices más adelante:
window.addEventListener('resize', () =>
{
// ...
camera.updateProjectionMatrix()
})
Finalmente, debemos actualizar renderer.
el procesador de actualización que actualizará automáticamente el ancho y el alto del lienzo :
window.addEventListener('resize', () =>
{
// ...
// Update renderer
renderer.setSize(sizes.width, sizes.height)
})
Código completo:
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)
})
Puede cambiar el tamaño de la ventana según sea necesario y el lienzo debe cubrir la ventana gráfica sin barras de desplazamiento ni desbordamiento.
Relación de procesamiento de píxeles
A medida que desarrollamos, algunas personas pueden ver una representación borrosa y artefactos con bordes en forma de escaleras (llamados aliasing), pero no todos lo verán. Si tiene problemas como este, es porque su pantalla tiene una proporción de píxeles superior a 1 .
La proporción de píxeles corresponde a cuántos píxeles físicos hay en la pantalla en una unidad de píxel de la parte de software.
algo de historia
Hace unos años, todas las pantallas tenían la misma proporción de píxeles 1
y todo iba bien. Pero cuando miras de cerca tu pantalla, puedes ver esos píxeles, que limitan la precisión de las imágenes y la finura de las fuentes.
La empresa que más ha hecho en este sentido es Apple. Apple vio una oportunidad y comenzó a fabricar 2
pantallas con proporciones de píxeles Retina. Ahora, muchos constructores están haciendo esto y puedes ver pantallas con proporciones de píxeles más altas.
Si bien esto es bueno para la calidad de la imagen, la proporción de píxeles 2
significa que también hay 4 veces más píxeles para renderizar. La proporción de píxeles 3
significa 9 veces más píxeles para renderizar.
¿adivina qué? Las proporciones de píxeles más altas generalmente se encuentran en dispositivos con las pantallas más pequeñas: dispositivos móviles.
Incluida la velocidad de fotogramas.
Relación de procesamiento de píxeles
window.devicePixelRatio
Obtenga la proporción de píxeles de la pantalla que puede usar, simplemente llame a renderer.setPixelRatio(...)
la proporción de píxeles del procesador de actualización después de obtener la proporción de píxeles.
Es posible que desee simplemente enviar la proporción de píxeles del dispositivo al método, pero terminará con problemas de rendimiento en dispositivos con una proporción de píxeles alta.
La relación de píxeles más grande 2
es principalmente para marketing. Tus ojos apenas pueden ver la diferencia entre 2
y 3
, pero puede crear problemas de rendimiento y agotar la batería más rápido. Una optimización que se puede hacer es limitar la proporción de píxeles a 2
.Para hacer esto, puede usar Math.min()
:
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
Existen técnicas para notificarnos a los desarrolladores cuando cambia la proporción de píxeles, pero solo afecta a los usuarios que tienen varias pantallas con diferentes proporciones de píxeles y, por lo general, cambian el tamaño de las ventanas cuando cambian de una pantalla a otra. Es por eso que simplemente agregamos este método a resize
la devolución de llamada:
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))
})
manejar pantalla completa
Ahora que nuestro lienzo ocupa todo el espacio disponible con la proporción de píxeles correcta, es hora de agregar soporte para pantalla completa.
Primero, debemos decidir qué acción activará el modo de pantalla completa. Podría ser un botón HTML, pero para nuestro ejemplo usaremos un doble clic para activar la pantalla completa.
Cuando ocurre el doble clic, cambiamos a pantalla completa, lo que significa que si la ventana no está en pantalla completa, el doble clic habilitará el modo de pantalla completa, y si la ventana ya está en pantalla completa, el doble clic saldrá del modo de pantalla completa.
Primero, debemos escuchar el evento de doble clic, que podemos dblclick
lograr a través del evento:
window.addEventListener('dblclick', () =>
{
console.log('double click')
})
Este evento funciona en la mayoría de los navegadores modernos excepto Chrome Android: https://developer.mozilla.org/docs/Web/API/Element/dblclick_event Ahora
que tenemos nuestro evento de doble clic, necesitamos tres cosas:
- Una forma de saber si ya está en pantalla completa
- Cómo entrar en el modo de pantalla completa
- Una forma de salir del modo de pantalla completa
Para saber si ya estamos en modo pantalla completa podemos usar document.fullscreenElement
:
window.addEventListener('dblclick', () =>
{
if(!document.fullscreenElement)
{
console.log('go fullscreen')
}
else
{
console.log('leave fullscreen')
}
})
Un método para solicitar pantalla completa está asociado con el elemento. Esto se debe a que puede elegir lo que va a pantalla completa. Puede ser toda la página, cualquier elemento DOM o <canvas>
.Usaremos
y <canvas>
llamaremos equestFullscreen()
a su método:
window.addEventListener('dblclick', () =>
{
if(!document.fullscreenElement)
{
canvas.requestFullscreen()
}
else
{
console.log('leave fullscreen')
}
})
El método para salir del modo de pantalla completa puede ser directamente en document
:
window.addEventListener('dblclick', () =>
{
if(!document.fullscreenElement)
{
canvas.requestFullscreen()
}
else
{
document.exitFullscreen()
}
})
Puede probar los resultados haciendo doble clic en cualquier lugar para alternar el modo de pantalla completa. Desafortunadamente, esto no funciona para Safari
Safari
los navegadores que se toman su tiempo para admitir oficialmente funciones simples como pantalla completa, necesitamos usar versiones prefijadas para que funcione para document.fullscreenElement
, canvas.requestFullscreen
y 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()
}
}
})
Todo debería funcionar bien en todos los navegadores modernos, compatible con todos los navegadores.