Cómo crear una galería de imágenes en Svelte

Alex Tomás
6 min readFeb 12, 2021

--

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 etiqueta style 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 propiedad imageHeight, por lo que coge por defecto 150 que es el valor por defecto declarado en Carousel.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 😉

--

--