How to Create a Carousel in 3 Ways in Svelte

Odewole Babatunde Samson

Introduction

Carousels, referred to as image sliders or sliders, provide an improved visual experience on websites by highlighting essential aspects of a product, service, or value proposition.

An Image Carousel is a series of images that are moved automatically with a timer or manually using some buttons.

This post discusses three different ways to create a carousel in a Svelte application.

Sandbox

The completed project is on CodeSandbox. Fork and run it to quickly get started.

View the source code on Github.

Prerequisites

The knowledge of the following is required:

  • Basic understanding of HTML, CSS, and JavaScript
  • Node and its package manager, npm (we run the command node -v && npm -v to verify we have them installed or install them from here)
  • A Cloudinary account for storing and delivering our images (Create a free one here)
  • Understanding Svelte would help us follow this tutorial quicker

Setting up a Svelte Project

Svelte is a radical new approach to building user interfaces. Svelte is a compiler and syntax. The entire Svelte project compiles into a single JavaScript file; it is not an external library included in the bundle like React, which allows Svelte projects to be tiny and fast.

To set up our Svelte project, we go to our terminal or command line and run:

1npx degit sveltejs/template svelte-carousel
2npm install
3npm run dev

This will create a new project in the svelte-carousel directory, install its dependencies, and start a server on http://localhost:8080.

Carousels don’t automatically create optimal slide dimensions. We will use additional utilities or custom styles to size it appropriately.

Uploading Images to Cloudinary

Cloudinary allows us to upload images via the dashboard by clicking the Media Library tab.

Next, we need to copy the publicId for the saved images from our dashboard, which will be necessary to generate the article banner.

Svelte Carousel

Svelte-carousel is an incredible component for Svelte 3. This carousel automatically cycles through a series of images, text, or custom markup. It supports next/prev controls and also supports indicators.

We start by installing the svelte-carousel with the following command so that we have access to the carousel component:

1npm install svelte-carousel

Next, let’s create a carousels folder in the src directory, and inside the folder, create SvelteCarousel.svelte file with the following code:

1<script>
2 import Carousel from "svelte-carousel";
3 const images = [
4 {
5 url: "https://res.cloudinary.com/beswift/image/upload/v1650391490/photo-1644241687200-eadaf7601290_xcz2kh.jpg",
6 description: "image1",
7 },
8 {
9 url: "https://res.cloudinary.com/beswift/image/upload/v1650391337/photo-1647067867267-e01d98462f3c_ugtnwe.jpg",
10 description: "image2",
11 },
12 {
13 url: "https://res.cloudinary.com/beswift/image/upload/v1650391131/photo-1648800475313-2bb7fbec8701_ae60yw.jpg",
14 description: "image3",
15 },
16 {
17 url: "https://res.cloudinary.com/beswift/image/upload/v1650390102/photo-1649894222226-056a1a79d9fb_xlv73h.jpg",
18 description: "image4",
19 },
20 {
21 url: "https://res.cloudinary.com/beswift/image/upload/v1650389425/photo-1649894221695-45abb718a190_sgjhwd.jpg",
22 description: "image5",
23 },
24 ];
25 let carousel; // for calling methods of the carousel instance
26 const handleNextClick = () => {
27 carousel.goToNext();
28 };
29</script>
30
31<Carousel
32 bind:this={carousel}
33 let:loaded
34 autoplay
35 autoplayDuration={3000}
36 autoplayProgressVisible
37>
38 {#each images as src, imageIndex (src)}
39 <div class="img-container">
40 {#if loaded.includes(imageIndex)}
41 <img src={src.url} alt={src.description} width={1000} height={600} />
42 {/if}
43 </div>
44 {/each}
45</Carousel>

From the code snippet above, we:

  • Import the Carousel dependency from svelte-carousel
  • Create an array of items that contain the URL and descriptions of the images
  • Create a variable called carousel for calling methods of the carousel instance
  • Declare a handleNextClick() function
  • Loop through the array with #each and then use the src as the key for the loop

In the App.svelte, let us clean it up, import the SvelteCarousel.svelte component, and render it.

1<script>
2 import Carousel from './carousels/SvelteCarousel.svelte'
3</script>
4
5<main>
6 <h1>Svelte-carousel</h1>
7 <Carousel />
8</main>

Now, if we go to the browser, we would see a functional carousel.

Svelte Transitions Carousel

Svelte contains some inbuilt transitions that are useful for creating an easy animation. Let’s learn about transitions in Svelte by creating an image carousel component.

We create a new file called SvelteTransition.svelte file in the src directory and start adding a simple image component.

1<script>
2 import {slide, fade} from 'svelte/transition';
3 import {elasticInOut} from 'svelte/easing';
4 const gallery_items = [
5 {
6 url: "https://res.cloudinary.com/beswift/image/upload/v1650390102/photo-1649894222226-056a1a79d9fb_xlv73h.jpg",
7 description: "Dog",
8 },
9 {
10 url: "https://res.cloudinary.com/beswift/image/upload/v1650391131/photo-1648800475313-2bb7fbec8701_ae60yw.jpg",
11 description: "Building",
12 },
13 {
14 url: "https://res.cloudinary.com/beswift/image/upload/v1650391337/photo-1647067867267-e01d98462f3c_ugtnwe.jpg",
15 description: "Staircase",
16 },
17 {
18 url: "https://res.cloudinary.com/beswift/image/upload/v1650391490/photo-1644241687200-eadaf7601290_xcz2kh.jpg",
19 description: "Staircase",
20 },
21 ];
22 let currentSlideItem = 0;
23 const nextImage = () => {
24 currentSlideItem = (currentSlideItem + 1) % gallery_items.length;
25 }
26 const prevImage = () => {
27 if (currentSlideItem != 0) {
28 currentSlideItem = (currentSlideItem - 1) % gallery_items.length;
29 } else {
30 currentSlideItem = gallery_items.length - 1;
31 }
32 }
33</script>
34
35 {#each [gallery_items[currentSlideItem]] as item (currentSlideItem)}
36 <img in:slide="{{ duration: 1000, easing: elasticInOut}}" out:fade src={item.url} alt={item.description} width={1000} height={600}/>
37 {/each}
38 <div class="carousel-buttons">
39 <button class="btn" on:click={() => prevImage()}>Previous</button>
40 <button class="btn" on:click={() => nextImage()}>Next</button>
41 </div>

From the code snippet above, we:

  • Import the required dependencies from svelte/transition
  • Create an array of items that contain the URL and descriptions of the images
  • Create a variable called currentSlideItem() which will decide the item to show from the array
  • Declare nextImage() and prevImage() function that’ll control the carousel
  • Then, loop through the array with #each and then using the src as the key for the loop
  • Invoke the nextImage() and prevImage() inside the button element

In the App.svelte, we import the SvelteTransition.svelte component, and render it.

1<script>
2 import Carousel from './carousels/SvelteCarousel.svelte'
3 import SvelteTransition from './carousels/SvelteTransition.svelte'
4</script>
5
6<main>
7 <h1>Svelte-carousel</h1>
8 <Carousel />
9 <h1>Svelte Transition</h1>
10 <SvelteTransition />
11</main>

Now, if we go to the browser, we would see a functional carousel.

Siema Carousel

Siema is a lightweight (only 3kb gzipped) carousel plugin with no dependencies and no styling. It is 100% open source and available on Github. It is free to use on personal and commercial projects.

We start by installing siema with the following command so that we have access to the carousel component:

1<script>
2 import Siema from 'siema';
3 import { onMount } from 'svelte';
4
5 let slider, prev, next, radioSlider
6 let select = 0
7
8 onMount(() => {
9 slider = new Siema({
10 selector: '.siema',
11 duration: 200,
12 easing: 'ease-in-out',
13 perPage: 2,
14 startIndex: 0,
15 draggable: true,
16 multipleDrag: true,
17 threshold: 20,
18 loop: true,
19 rtl: false,
20 onInit: () => {},
21 onChange: () => {},
22 }); //end Siema constructor
23 prev = () => {
24 slider.prev()
25 if (select > 0) {
26 select--
27 }
28 }
29 next = () => {
30 slider.next()
31 if (select >= 0) {
32 select++
33 }
34 }
35 }) //end onMount
36 const images = [
37 {
38 url: "https://res.cloudinary.com/beswift/image/upload/v1650391490/photo-1644241687200-eadaf7601290_xcz2kh.jpg",
39 description: "image1",
40 },
41 {
42 url: "https://res.cloudinary.com/beswift/image/upload/v1650391337/photo-1647067867267-e01d98462f3c_ugtnwe.jpg",
43 description: "image2",
44 },
45 {
46 url: "https://res.cloudinary.com/beswift/image/upload/v1650391131/photo-1648800475313-2bb7fbec8701_ae60yw.jpg",
47 description: "image3",
48 },
49 {
50 url: "https://res.cloudinary.com/beswift/image/upload/v1650390102/photo-1649894222226-056a1a79d9fb_xlv73h.jpg",
51 description: "image4",
52 },
53 {
54 url: "https://res.cloudinary.com/beswift/image/upload/v1650389425/photo-1649894221695-45abb718a190_sgjhwd.jpg",
55 description: "image5",
56 },
57 ];
58 </script>
59 <main>
60 <div class="siema">
61 {#each images as src, imageIndex (src)}
62 <div class="slider">
63 <img src={src.url} alt={src.description} width={1000} height={600} />
64 </div>
65 {/each}
66 </div>
67 </main>
68 <button on:click={prev}>
69 prev
70 </button>
71 <button on:click={next}>
72 next
73 </button>

From the code snippet above, we:

  • Import the required dependencies
  • Create an array of items that contain the URL and descriptions of the images
  • Passed the Siema() constructor onMount of the app. The Siema() constructor has argument of selector, duration, easing, perPage, startIndex, draggable, multipleDrag, etc
  • Declare prev() and next() function that’ll control the carousel
  • Then, loop through the array with #each and then using the src as the key for the loop
  • Invoke the next() and prev() inside the button element

In the App.svelte, we import the SvelteSiema.svelte component, and render it.

1<script>
2 import Carousel from './carousels/SvelteCarousel.svelte'
3 import SvelteTransition from './carousels/SvelteTransition.svelte'
4 import SvelteSiema from './carousels/SvelteSiema.svelte'
5</script>
6
7<main>
8 <h1>Svelte-carousel</h1>
9 <Carousel />
10 <h1>Svelte Transition</h1>
11 <SvelteTransition />
12 <h1>Svelte Transition</h1>
13 <SvelteTransition />
14</main>

Now, if we go over to the browser, we would see a functional carousel.

Conclusion

We discussed three different ways to add a carousel in a svelte project. Although this post covers the basic implementation of these carousels, there are more configurations in their various documentation.

Resources

Odewole Babatunde Samson

Software engineer and Technical writer

I am a self-driven and self-motivated software engineer in the blockchain development space and I love to impact more knowledge to people that is why I write about Javascript, React.js, web3.js, and Solidity