Curved Image Carousel Coded in Svelte with Swipe and Grabbing Functionality for Smartphones

A neat image carousel coded in Svelte and therefore an up-to-date web app with swipe and grabbing functionality. Easily adaptable to own needs.

Tuedo#008

 by  tuedodev

13
Nov 2021
 0

What´s all the fuss about Svelte, you might ask. There are a variety of answers to this question, but one prominent feature is without a doubt its capability to deliver just the compiled Javascript code for production. Ready to run the Javascript code can be together with the CSS stylesheet included in a static HTML page without any further dependencies.

So it makes sense to realize a complex user interface like an image carousel with the help of Svelte. In our case, the carousel should not only move from left to right or from right to left, but also have a curved course and be fit for smartphones.

Github Repository of the Code

CodePen Live-Demo

In addition to Svelte as a framework, for this task we use Material Design from Google to quickly and without detour adapt buttons and cards. Material Design is an abundant resource with many useful components when it comes to smooth interactions between user and web applications1.

Trajectory of the images: a curve, not a circle

CurvedCarousel.svelte acts as the main component of the app, which is built in the usual svelte structure: script - HTML markdown and preprocessor styling (here SCSS instead of CSS). The following formula is used to calculate the position and also the tilt angle of the individual image.

// Functions for graph
const graph = (x) => -((Math.pow(x, 2) - 36) / 18) - 2;
const derivation = (x) => -x / 9;
const angle = (x) => (180 / Math.PI) * Math.atan(derivation(x));

Some might wonder why we did not use a circular function here in the calculation, but rather a graph. The reason is aesthetic. With the circle function the images would be curved very quickly at the edges, with the graph a circular movement of the images is only simulated, which in our experience has shown better results.

Those graphs of a function will be mainly used by the Javascript function calculateSlidePosition, which will return a calculated position and rotation object to a given x position as argument.

function calculateSlidePosition(xPosition) {
	let rotate = angle(xPosition);
	let xpos = xPosition * slideWidth * 0.9;
	let yCurve = graph(xPosition) * (vh / 1.5);
	let ypos = -yCurve;
	return { xpos, ypos, rotate };
}

Said x position is a calculated value that takes into account the current index value of the image (the function is called from an array loop) and the mouse movement of the draggable image stored in the variable movedBy.

The event handler grabEndHandler is of special importance when the mouse button is released (or when the touching event is triggered on the smartphone).


function grabEndHandler(event) {
	let ratio = movedBy / slideWidth;
	movedBy = 0;
	isDragging = false;
	if (Math.abs(ratio) >= 0.2) {
		let add = Math.sign(ratio) * -1;
		updateCurrentIndex(add);
	} else {
		setSliderPosition();
	}
}

The if-condition then checks whether the movement was sufficient enough to justify switching to the next or previous image (true) or whether the image falls back to the original position (false). The ratio value, as the name implies, reflects the ratio between motion length and image width. Of course, you can play with those numbers in order to get a different behaviour.

Using Svelte´s built-in transition and animation methods

If you take a look at the HTML markup, you'll notice that Svelte's built-in transition method fly is used to show and hide the caption of the currently focused image. This underlines another advantage of Svelte as compared to other frameworks when it comes to transitions and animations.

So it's worth looking into Svelte, especially since SvelteKit is an even more comprehensive tool that's in the same league as React, Gatsby, and Next JS.

  1. At this point it should be mentioned that there are similar resources specified for Svelte, including Svelte Material UI, but it was the better documentation that counted and guess what, it's all Javascript code in the end.

This post has not been commented on yet.

Add a comment