Artículo original: 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 😉
Top comments (2)
Gracias por subir un post en español, se que no tienen tanta tracción como en inglés pero habemos muchos que los disfrutamos y muchos otros que los necesitan realmente.
Hablando de Svelte, es la primera vez que veo un ejemplo de implementación.
Ahora viendo esto:
Si JSX me parecia raro, ya esto no se ni como mirarlo la verdad o el
Creo que VueJS sigue en la delantera en cuanto a legibilidad verdad? (repito, es la primera vez que veo código para Svelte)
Hola Saulo, gracias por tu mensaje.
Es lo que Svelte llama "keyed each blocks", con un poco raros de ver la verdad, te dejo un ejemplo de la propia documentación de Svelte a ver que te parece: svelte.dev/tutorial/keyed-each-blocks 😉