Cómo crear una galería de imágenes en Svelte
--
Introducción
En este artículo veremos como crear una galería de imágenes en Svelte (carousel gallery) de una forma muy sencilla, creando tu propio componente y sin necesidad de plugins o librerías externas.
¡Así que vamos a empezar! 💃🏻
Crear un nuevo proyecto Svelte
Para crear un proyecto en Svelte, recordemos, con el siguiente comando:
npx degit sveltejs/template <Nombre_del_proyecto>
Para el ejemplo voy a llamar el proyecto galeria-svelte
:
npx degit sveltejs/template galeria-svelte
Degit
clona solo el espacio de trabajo publicado de git y no el repositorio.
Entonces, sólo nos queda instalar las dependencias con yarn install
o npm install
(eso ya a tu elección, yo usaré NPM).
cd galeria-svelte
npm install
Bien. Ya tenemos instalado nuestro nuevo proyecto para crear nuestra awesome galería de imágenes 🙃 Si ejecutas npm run dev
deberías ver tu proyecto en http://localhost:5000/
:
Componente <Carousel />
Vamos a crear nuestro componente básico para ver nuestra galería, que lo llamaremos Carousel
:
// Carousel.svelte
<script>
export let images;
</script>
Como verás, con export let images
le estamos diciendo al componente que le enviaremos por props
una variable (que será un array de imágenes) llamada images
.
<!-- Carousel.svelte -->
<div class="carousel">
<div class="carousel__container">
{#each images as image (image.id)}
<img src={image.path} alt={image.alt} id={image.id} height="100" />
{/each}
</div>
</div>
El html es muy sencillo de momento. Hacemos un loop del array de imágenes que recibimos por parámetro y ponemos una imagen para cada item.
/* Carousel.svelte */
<style>
.carousel {
display: flex;
overflow-x: auto;
position: relative;
width: 100%;
}
.carousel__container {
display: flex;
}
</style>
Y finalmente le damos un poco de estilo, para ver todas las imágenes una al lado de la otra, y en el caso de que tengamos más imagenes y no entren en el ancho de la página, nos haga un scroll horizontal.
El Carousel.svelte
completo quedaría de la siguiente forma:
<script>
export let images;
</script><div class="carousel">
<div class="carousel__container">
{#each images as image (image.id)}
<img src={image.path} alt={image.alt} id={image.id} height="100" />
{/each}
</div>
</div><style>
.carousel {
display: flex;
overflow-x: auto;
position: relative;
width: 100%;
}
.carousel__container {
display: flex;
}
</style>
¿Cómo puedo utilizar mi <Carousel />
?
Para utilizar un componente en Svelte, como en otros frameworks de JavaScript es muy muy MUY fácil. Importamos el componente y lo llamamos como una etiqueta html. Vamos a verlo con un ejemplo, para ello editaremos el fichero src/App.svelte
de ejemplo que nos genera el propio Svelte al crear el proyecto. Lo dejaremos de la siguiente forma:
<script>
import Carousel from './Carousel.svelte';
const images = [
{
path: 'https://picsum.photos/id/1012/3973/2639',
id: 'imagen-ejemplo-1',
alt: 'Atributo ALT de ejemplo para la imagen #1',
},
{
path: 'https://picsum.photos/id/1005/5760/3840',
id: 'imagen-ejemplo-2',
alt: 'Atributo ALT de ejemplo para la imagen #2',
},
{
path: 'https://picsum.photos/id/1020/4288/2848',
id: 'imagen-ejemplo-3',
alt: 'Atributo ALT de ejemplo para la imagen #3',
},
{
path: 'https://picsum.photos/id/1025/4951/3301',
id: 'imagen-ejemplo-4',
alt: 'Atributo ALT de ejemplo para la imagen #4',
},
{
path: 'https://picsum.photos/id/103/2592/1936',
id: 'imagen-ejemplo-5',
alt: 'Atributo ALT de ejemplo para la imagen #5',
},
{
path: 'https://picsum.photos/id/104/3840/2160',
id: 'imagen-ejemplo-6',
alt: 'Atributo ALT de ejemplo para la imagen #6',
},
];
</script><main>
<h2 class="item__title">Mi galería de ejemplo</h2>
<div class="item__gallery">
<Carousel {images} />
</div>
<p class="item__description">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae ipsum
possimus accusamus aut, assumenda fuga labore provident, non molestiae
recusandae harum, fugit neque nisi quos qui nulla. Non, quaerat officia.
</p>
</main><style>
main {
padding: 1em;
max-width: 800px;
margin: 0 auto;
}
</style>
Como verás, importamos el componente con import Carousel from './Carousel.svelte';
y definimos un array de imagenes con tres atributos (path, id, alt). E invocamos el componente Carousel
pasándole el array de imágenes que nos hemos definido anteriormente:
<Carousel {images} />
Si todo ha funcionado correctamente, que seguro que sí 🕵🏻♂️, deberías de ver nuestro primer carousel de imágenes:
Fácil, ¿no?
Parametrizar el componente
La gracia de los componentes es que podemos querer reutilizarlos en otras partes de la web, con diferentes parámetros y estilo, ¿no? Por ejemplo, en nuestro caso, podríamos querer diferentes tamaños de imagen para una galería u otra, o bien una separación entre imágenes, ¡o ambas cosas! Vamos a ello.
Tamaño de imagen variable en nuestra galería
Vamos a definir un nuevo parámetro imageHeight
en nuestro Carousel.svelte que será el tamaño máximo de las imágenes:
// ...
// Alto máximo por defecto de 150px
export let imageHeight = 150;
// ...
Y se lo pasamos al html de la siguiente forma:
<!-- ... -->
<img
src={image.path}
alt={image.id}
id={image.id}
style={`height: ${imageHeight}px;`}
/>
<!-- ... -->
Elimina la la propiedad
height="100"
que le pasábamos inicialmente porque ahora se lo vamos a pasar dinámicamente. Se lo añado a la etiquetastyle
porque luego le pasaremos otra propiedad css 🙃
Y ahora ya podemos crear nuestra galerías con diferentes tamaños de imagen.
Galería de imágenes con 200px de alto
<Carousel {images} imageHeight={200} />
Galería de imágenes con 275px de alto
<Carousel {images} imageHeight={275} />
Y por supuesto puedes reutilizar el componente y poner dos galería con diferentes tamaños:
<Carousel {images} imageHeight={205} />
<Carousel {images} />
Nota que al segundo
Carousel
no le he pasado la propiedadimageHeight
, por lo que coge por defecto 150 que es el valor por defecto declarado enCarousel.svelte
🎉
Separación entre imágenes
Vamos a hacer otra pequeña configuración. Vamos a separar, o no, las imágenes entre sí. Para ello usaremos una nueva propiedad llamada imageSpacing
:
// ...
// Por defecto las imágenes no van separadas
export let imageSpacing = 0;
// ...
Y se lo pasamos al html de la siguiente forma:
<!-- ... -->
<img
src={image.path}
alt={image.id}
id={image.id}
style={`height: ${imageHeight}px; margin-right: ${imageSpacing}px`}
/>
<!-- ... -->
Y ahora ya podemos crear nuestra galerías con las imágenes separadas los pixels que quedamos, por ejemplo:
Galería de imágenes de 140px de alto y separadas 3px
<Carousel {images} imageHeight={140} imageSpacing={3} />
Cómo verás es muy sencillo su configuración y su uso.
Código final
Finalmente el componente debería haberte quedado así:
<script>
export let images;
export let imageHeight = 150;
export let imageSpacing = 0;
</script><div class="carousel">
<div class="carousel__container">
{#each images as image (image.id)}
<img
src={image.path}
alt={image.alt}
id={image.id}
style={`height: ${imageHeight}px; margin-right: ${imageSpacing}px`}
/>
{/each}
</div>
</div><style>
.carousel {
display: flex;
overflow-x: auto;
position: relative;
width: 100%;
}
.carousel__container {
display: flex;
}
</style>
Repositorio en Github
Repo: https://github.com/alextomas80/galeria-imagenes-svelte
Y esto es todo. Espero que te pueda servir 😉