Gestión de puntos de ruptura de imagen con Angular
Publicado: 2022-03-10Como desarrolladores web, a menudo se nos pide que creemos aplicaciones que respondan y que sean ricas en medios. Tener tales requisitos significa que debemos trabajar con puntos de interrupción de imágenes, así como con consultas de medios, ya que queremos brindar la mejor experiencia a los usuarios finales. Agregando a la lista de requisitos, es posible que necesitemos usar un marco de front-end como Angular, que es excelente para crear SPA y otros tipos de aplicaciones.
En este artículo, veremos los puntos de ruptura de imágenes, sus casos de uso y un ejemplo práctico; los implementaremos en una aplicación Angular usando el propio BreakPoint Observer de Angular. Mientras usamos este enfoque, también destacaremos por qué este marco popular nos ayuda a trabajar con las técnicas antes mencionadas de manera fluida.
Puntos de interrupción de imagen e imágenes receptivas
En la era de los diseños receptivos (donde capturamos puntos de interrupción según el tamaño de la ventana gráfica y, en función del punto de interrupción, cambiamos el diseño de la página), también debemos asegurarnos de que las imágenes se puedan mostrar con las dimensiones correctas, incluso después de un diseño. cambiar. Seleccionar la imagen correcta es todo un desafío para los sitios web receptivos modernos.
Analicemos dos opciones que los desarrolladores pueden utilizar en este momento.
srcset
srcset
nos permite definir una lista de imágenes entre las que cambia el navegador en función del tamaño <img>
representado y la densidad de la pantalla.
Echemos un vistazo a un ejemplo:
<img src="tuscany.jpg" />
En lo anterior, especificamos 3 imágenes, donde la w
indica el ancho de píxel de la imagen. Cuando usamos lo anterior con srcset
, también necesitamos especificar el atributo de sizes
(esto es obligatorio porque la especificación exige que si usamos srcset
y w
también debemos tener un atributo de tamaños). ¿Cuál es el propósito de este atributo? Los navegadores deben elegir qué recurso cargar de un conjunto de fuentes antes de diseñar la página (antes de saber qué tamaño terminará teniendo la imagen). Podemos pensar en los sizes
como una pista para el navegador de que, después del diseño, la imagen ocupará el 100% del ancho de la ventana gráfica (a eso se refiere vw
). El navegador conoce el ancho real de la ventana gráfica (así como el DPR de la imagen) en el momento de la carga, por lo que puede hacer los cálculos para determinar qué tamaño de recurso necesita y elegir uno del conjunto de fuentes.
Las combinaciones de elementos <picture>
y <source media="">
nos permiten cambiar los recursos de imagen en respuesta a consultas de medios, como las que se encuentran en los puntos de interrupción del diseño.
Echemos un vistazo a un ejemplo de esto también:
<picture> <source media="(min-width: 1440px)"> <source media="(min-width: 900px)"> <source media="(min-width: 600px)"> <img src="../assets/images/tuscany-sm.jpg" /> </picture>
Cambie el código de arriba localmente con una imagen de su elección que tenga un tamaño pequeño, mediano y grande. Observe cómo, al cambiar el tamaño del navegador, obtiene una imagen diferente.
La conclusión clave de todo lo anterior es que si queremos intercambiar imágenes en puntos de interrupción específicos, podemos usar el elemento <picture>
para colocar consultas de medios directamente en el marcado.
Nota : si está interesado en explorar las diferencias entre <picture>
y srcset
+ sizes
, le recomiendo leer el gran artículo de Eric Portis: srcset
y sizes
.
Hasta ahora hemos discutido cómo usar puntos de ruptura de imagen junto con consultas de medios en un entorno HTML puro. ¿No sería mucho mejor tener una forma conveniente, casi semiautomática, de generar puntos de interrupción de imágenes, así como las imágenes correspondientes para los puntos de interrupción, incluso sin tener que especificar consultas de medios? Afortunadamente para nosotros, Angular tiene un mecanismo incorporado para ayudarnos y también veremos cómo generar las imágenes apropiadas dinámicamente según ciertas condiciones mediante el uso de un servicio de terceros.
Módulo de diseño angular
Angular viene con un módulo de diseño que vive en el conjunto de herramientas CDK (kit de desarrollo de componentes). Angular CDK contiene herramientas bien probadas para ayudar con el desarrollo de componentes. Una parte del CDK es el módulo de diseño que contiene un BreakpointObserver
. Este ayudante brinda acceso a los puntos de interrupción de consulta de medios, lo que significa que los componentes (y sus contenidos) pueden adaptarse a los cambios cuando el tamaño del navegador (tamaño de la pantalla) se cambia de manera intuitiva.
Lectura recomendada : Módulo de diseño
Ahora que tenemos la teoría fuera del camino, vayamos al grano y creemos una aplicación que implementará puntos de interrupción de imagen sensibles. En esta primera iteración, crearemos el shell de la aplicación a través de Angular CLI: ng new bpo
y seleccionaremos las opciones necesarias.
Para usar BreakpointObserver
, también necesitamos instalar el módulo de diseño de CDK de Angular, lo que podemos hacer a través de npm: npm i @angular/cdk
.
Tras la instalación, podremos añadir las declaraciones de importación necesarias a cualquier componente que deseemos:
// app.component.ts import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
Al usar BreakpointObserver
, podemos suscribirnos a los cambios en el ancho de la ventana gráfica y Angular nos brinda accesos convenientes, lo que significa que no necesitamos usar consultas de medios en absoluto. Sigamos adelante y probemos esto:
// app.component.ts constructor(public breakpointObserver: BreakpointObserver) { } ngOnInit() { this.breakpointObserver.observe([ Breakpoints.XSmall, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge ]).subscribe(result => { if (result.breakpoints[Breakpoints.XSmall]) { // handle XSmall breakpoint } if (result.breakpoints[Breakpoints.Small]) { // handle Small breakpoint } if (result.breakpoints[Breakpoints.Medium]) { // handle Medium breakpoint } if (result.breakpoints[Breakpoints.Large]) { // handle Large breakpoint } if (result.breakpoints[Breakpoints.XLarge]) { // handle XLarge breakpoint } }); }
Como se mencionó antes, las propiedades del acceso anterior reflejan las consultas de medios de la siguiente manera:

-
Breakpoints.XSmall
: ancho máximo = 599.99px -
Breakpoints.Small
: ancho mínimo = 600 px y ancho máximo = 959.99 px - Puntos de
Breakpoints.Medium
: ancho mínimo = 960 px y ancho máximo = 1279.99 px -
Breakpoints.Large
: ancho mínimo = 1280 px y ancho máximo = 1919.99 px - Puntos de
Breakpoints.XLarge
: ancho mínimo = 1920px
Ahora tenemos todo en su lugar, lo que significa que podemos comenzar a generar las imágenes apropiadas.
Puntos de interrupción receptivos para imágenes
Tenemos algunas opciones para generar imágenes responsivas:
- Generador de puntos de interrupción de imagen receptiva
Con esta herramienta, podemos cargar cualquier imagen, configurar varias opciones, por ejemplo, la cantidad de imágenes que deseamos generar. Después de ejecutar la herramienta, tendremos una representación visual de las imágenes generadas y podremos descargarlas como un archivo zip junto con un código generado que utiliza el elemento<picture>
mencionado anteriormente. - Otra solución sería crear un paso de compilación para que nuestro proyecto genere puntos de interrupción a través de algunos paquetes disponibles en el repositorio de NPM, como
gulp-responsive
ogrunt-responsive-images
. Ambos dependen de bibliotecas adicionales que debemos instalar para nuestro sistema operativo. (Consulte los repositorios apropiados para obtener información adicional). - Otra solución más sería usar un servicio como Cloudinary para almacenar las imágenes y servirlas en un tamaño y formato que solo necesitemos modificando la URL del recurso solicitado. Este será nuestro enfoque ya que esto nos da la mayor flexibilidad.
Lectura recomendada : Automatización de la dirección de arte con el generador de puntos de ruptura de imagen sensible por Eric Portis
He subido la imagen original a mi cuenta de Cloudinary, lo que significa que puedo acceder a esa imagen a través de la siguiente URL:
https://res.cloudinary.com/tamas-demo/image/upload/breakpoints-article/tuscany.jpg
Esta es la imagen de tamaño completo, sin procesar, original y sin cambios con la que trabajaremos.
Podemos modificar la URL de la imagen para generar una versión mucho más pequeña. Por ejemplo, si queremos tener una imagen con un ancho de 600 píxeles, podríamos actualizar la URL de Cloudinary* para que sea la siguiente:
https://res.cloudinary.com/tamas-demo/image/upload/w_600/breakpoints-article/tuscany.jpg
* Tenga en cuenta el w_600
agregado a la URL.
Con suerte, en este punto, usted ve a dónde va todo esto. Según el enfoque anterior, podemos comenzar a generar rápidamente la imagen correcta para el punto de interrupción correcto.
El uso de Cloudinary significa que no necesitamos crear, almacenar y administrar varias versiones de la misma imagen; Cloudinary lo hace por nosotros sobre la marcha.
Actualicemos nuestro código:
<!-- app.component.html --> <div> <h1>Current breakpoint: {{ breakpoint }}</h1> <img [src]="imagePath"> </div>
// app.component.ts import { Component, OnInit } from '@angular/core'; // ... export class AppComponent implements OnInit { imagePath; constructor(public breakpointObserver: BreakpointObserver) { } ngOnInit() { this.breakpointObserver.observe([ ... } }
Podemos elegir cualquier cantidad de puntos de interrupción para observar de la lista mencionada anteriormente, y dado que tenemos un observador, podemos suscribirnos a los cambios y actuar sobre ellos:
this.breakpointObserver.observe([ Breakpoints.XSmall, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge ]).subscribe(result => { if (result.breakpoints[Breakpoints.XSmall]) { // handle this case } });
Para manejar las opciones de las diferentes imágenes en Cloudinary, utilizaremos un enfoque que será muy fácil de seguir. Para cada caso, crearemos una variable de opciones y actualizaremos la URL final de Cloudinary.
Agregue lo siguiente en la parte superior de la definición del componente:
// app.component.ts imagePath; breakpoint; cloudinaryOptions; baseURL = 'https://res.cloudinary.com/tamas-demo/image/upload/breakpoints-article/tuscany.jpg';
Y agregue lo siguiente también a la primera declaración if
:
// app.component.ts let url = this.baseURL.split('/'); let insertIndex = url.indexOf('upload'); const options = 'c_thumb,g_auto,f_auto,q_auto,w_400'; url.splice(insertIndex + 1, 0, options); this.imagePath = url.join('/'); this.breakpoint = Breakpoints.XSmall;
El resultado será una URL de Cloudinary actualizada:
https://res.cloudinary.com/tamas-demo/image/upload/c_thumb,g_auto,f_auto,q_auto,w_400/breakpoints-article/tuscany.jpg
¿Cuáles son las opciones que estamos configurando aquí?
-
c_thumb
(genera una miniatura de la imagen); -
g_auto
(se enfoca en la parte más interesante; vemos la catedral en la miniatura); -
f_auto
(sirve el formato más apropiado para un navegador determinado, es decir, WebP para Chrome); -
q_auto
(reduce la calidad, y por lo tanto el tamaño general, de la imagen sin afectar las imágenes); -
w_400
(establece el ancho de la imagen en 400 px).
En aras de la curiosidad, comparemos el tamaño de la imagen original con esta imagen recién generada: ¡2,28 MB frente a 29,08 KB!
Ahora tenemos un trabajo sencillo: necesitamos crear diferentes opciones para diferentes puntos de interrupción. Creé una aplicación de muestra en StackBlitz para que pueda probarla de inmediato (también puede ver una vista previa aquí).
Conclusión
La variedad de dispositivos de escritorio y móviles y la cantidad de medios utilizados en la web actual ha alcanzado un número sobresaliente. Como desarrolladores web, debemos estar a la vanguardia en la creación de aplicaciones web que funcionen en cualquier dispositivo y no afecten la experiencia visual.
Hay una buena cantidad de métodos que aseguran que la imagen correcta se cargue en el dispositivo correcto (o incluso al cambiar el tamaño de un dispositivo). En este artículo, revisamos un enfoque que utiliza una función Angular integrada llamada BreakPoint Observer que nos brinda una interfaz poderosa para manejar imágenes receptivas. Además, también echamos un vistazo a un servicio que nos permite servir, transformar y gestionar imágenes en la nube. Con herramientas tan convincentes en nuestras manos, aún podemos crear experiencias web visuales inmersivas, sin perder visitantes.