In recent times, we have seen that the web is no longer a page in a browser full of squares. Every day there are more designs which incorporate irregular shapes.

In this tutorial we want to teach you how to create and animate shapes with a jelly effect. At the end, you will be able to create the jelly shape you want, and animate it according to your needs without too much effort.

Specifically, in this first part we will see how to achieve the following result:

The maths behind an effect like this can be very difficult to achieve. That's why we have tried to group the code needed to create and animate jelly shapes in a library that is easy to use for developers.

At the same time, we have been inspired by this pen by Thom Chiovoloni, inspired as well in the game The Floor is Jelly. And we have started specifically from this implementation of the jelly physics.

So, we've packaged this implementation into a library we've just called jelly.js, to which we've added everything we need to get jelly shapes easily. Then let's see how to use it!

We have chosen SVG paths to create the shapes, because we believe it is the easiest and most customizable way we have to do it. In this way, we can create the shapes that we want in a vector editor (like Inkscape or Illustrator), and insert them directly into our HTML document, or even import them from JavaScript.

For example, we can draw a simple shape like this:

Upgrade Your JS Go from vanilla JavaScript 👉 React

Watch for FREE

Then we can include the relevant SVG code directly in the HTML:

< svg xmlns = " http://www.w3.org/2000/svg " version = " 1.1 " width = " 400 " height = " 400 " style = " display: none " > < path id = " pentagon-path " d = " m200 97.218 108.07 78.524-41.28 127.04h-133.58l-41.281-127.04z " /> </ svg >

We also need a canvas to draw the shape, and some other elements with the aim of moving a letter (S, from Scotch) coordinately with the centroid (average point) of the shape.

< div class = " jelly-container " > < canvas class = " jelly-canvas " > </ canvas > < div class = " centroid-container " > < div class = " centroid-text " > S </ div > </ div > </ div >

For this example we need very few styles. Let's see the code:

html, body { margin : 0 ; } body { background-color : #D98327 ; overflow : hidden ; } .jelly-container { position : relative ; display : inline-block ; left : 50% ; margin-left : - 200 px ; } .jelly-container , .jelly-canvas { width : 400 px ; height : 400 px ; } .centroid-container { position : absolute ; left : 0 ; top : 0 ; transform : translate ( - 50% , - 50% ) ; pointer-events : none ; } .centroid-text { font-size : 100 px ; color : white ; }

Finally we have arrived at the most fun part! Let's draw our pentagon on the canvas and see how we can animate it in a jelly way. But don't worry, it will be very easy using our library.

We just need a few lines of code to draw our pentagon, and to get it reacting in a jelly way if we move the mouse to the edges of the shape:

var options = { paths : '#pentagon-path' , pointsNumber : 10 , maxDistance : 70 , color : '#5C1523' , centroid : '.centroid-text' } ; var jelly = new Jelly ( '.jelly-canvas' , options ) ;

Note that the constructor of our library ( Jelly ) receives a canvas element and a set of options. We can also provide an array of options, a set of options for each shape we want to draw. For a detailed description of the available options, you can check the Github repository.

We could leave it there, but our library has much more to offer. So let's look at some other things we can do.

To illustrate a little more the options we have (and for fun), let's see how we can shake our pentagon as we drag it across the screen.

First, we need to know when the mouse is inside the shape, to allow dragging it only when that happens. Check the following code, doing just that:

var container = document . querySelector ( '.jelly-container' ) ; var hoverIndex = - 1 ; function checkHover ( ) { hoverIndex = jelly . getHoverIndex ( ) ; container . style . cursor = hoverIndex === - 1 ? 'default' : 'pointer' ; window . requestAnimationFrame ( checkHover ) ; } window . requestAnimationFrame ( checkHover ) ;

And let's see how we can implement a basic dragging logic. Please look at the comments to understand what is happening there, and pay special attention to the shake function:

var startX , startY , dx , dy , endX = 0 , endY = 0 , x = 0 , y = 0 , lastX = 0 , lastY = 0 ; var down = false ; var shakeLimit = 5 ; container . addEventListener ( 'mousedown' , function ( e ) { if ( hoverIndex >= 0 ) { startX = e . clientX ; startY = e . clientY ; down = true ; } } ) ; document . addEventListener ( 'mousemove' , function ( e ) { if ( down ) { x = e . clientX - startX ; y = e . clientY - startY ; container . style . transform = 'translate(' + ( endX + x ) + 'px, ' + ( endY + y ) + 'px)' ; dx = x - lastX ; dy = y - lastY ; if ( dx > shakeLimit || dx < - shakeLimit ) dx = dx < 0 ? - shakeLimit : shakeLimit ; if ( dy > shakeLimit || dy < - shakeLimit ) dy = dy < 0 ? - shakeLimit : shakeLimit ; jelly . shake ( { x : - dx , y : - dy } ) ; lastX = x ; lastY = y ; } } ) ; function mouseUp ( ) { if ( down ) { down = false ; endX += x ; endY += y ; } } document . addEventListener ( 'mouseup' , mouseUp ) ; document . addEventListener ( 'mouseout' , function ( e ) { if ( e . target . nodeName == 'HTML' ) { mouseUp ( ) ; } } ) ;

The browser support is really good, because all modern browsers have support for canvas . But jelly.js uses Promises, so we need a polyfill for any browser that does not support native promises.

On the other hand, the performance is very variable according to the browsers and the operating systems. This is due to the CPU intensive work in each animation frame. So, don't abuse the use of these effects, because they can kill website performance.

And we are done! So far we have created a truly jelly pentagon without too much effort. Our shape also change the cursor on hover event, and respond to dragging in a jelly way as well :)

You can see the final demo here, and you can get the full code on Github too.

These are not the only things we can do. In fact, in the second part of this tutorial we will build an awesome slider, where everything will be jelly. In broad outline, we will learn how to:

Draw more jelly shapes, and text!

Use images inside the shapes, not only solid colors.

Animate the shapes to show or hide them smoothly.

Morph from a jelly shape to another.

Make the entire slider responsive.

We really hope you enjoyed it and found it useful! See you in the second part ;)

Like this article? Follow @lmgonzalves on Twitter