Playful Interaction for Draggable Elements

A little playful interaction idea where we add some bounciness to a draggable element and animate it depending on its position.

Today we’d like to share two tiny fun interaction experiments with you. The first one is inspired by Rally Interactive’s Dribbble shot. We wanted to create a playful dragging interaction that will morph and animate an element depending on its position. If dragged outside of the defined bounds, we will dismiss the element (demo 1), or navigate a gallery (demo 2). If dropped before the bounds we will snap the element back with an elastic effect. We also add some bounciness to inner elements so that everything gets an even more organic feel.

Attention: This experiment uses some CSS properties that won’t work in older browsers (CSS Animations, CSS Filters, etc.). Internet Explorer 11 neither supports transform-style: preserve-3d nor CSS filters.

We are using Draggabilly plus imagesLoaded by Dave de Sandro and Dynamic.js by Michaël Villar.

When dragging the respective element, we “morph” it so that we add some kind of depth feeling to the interaction. In the first demo we use a dialog where we animate the inner element on drag and the links when letting it bounce back. The second example is a gallery where we navigate when dragging the current image out of bounds (either to the left or to the right). The image morphs into a little polaroid with optional transforms (like scaling or rotating) or filters.

The interesting part of the workings of this effect is the calculation of the transform during the morphing. Given a certain distance we want a transform or filter to increase proportionally. To get to the right value, we need to find the appropriate mapping function that, given a point in our 2D space, returns the relative transform or filter value.

So what we do is to solve a linear function. Given two points in our coordinate system, we get our function and given a distance x, we get our y value. Let’s do an example with an element that is centered on the page and that decreases its opacity when moving to the sides of the page. Our distance is half of the window width: ww/2. Our opacity value ranges between 0 and 1. Full opacity is the center of the element and the page. Zero opacity is reached when the edges of the page are reached, hence ww/2 away from the original point. This gives us two points P1( x1, y1 ) and P2( x2, y2 ): P1( 0, 1 ) and P2( ww/2, 0 ):


With these two points we can get to our linear function like this:

f(x) = y = (( y2 – y1 ) / ( x2 – x1 )) * x + b

We know that b is 1, which is the intersection with the y-axis. When we resolve this using our two points, then we end up having:

f(x) = y = (2/ww) * x + 1

This function will, given a distance x, return the desired opacity level y.

The same principle holds for filter values (just use the values 0% and 100% for y1 and y2) or any other property you’d like to proportionally change.

We hope you enjoy this little experiment and find it inspiring!

Tagged with:

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

👾 Hey! Looking for the latest in frontend? Twice a week, we'll deliver the freshest frontend news, website inspo, cool code demos, videos and UI animations right to your inbox.

Zero fluff, all quality, to make your Mondays and Thursdays more creative!

Feedback 13

Comments are closed.
  1. I love going the extra mile with projects. Love the animations and interactions, super cool! Feels intuitive to drag to dismiss, awesome job.

  2. This is amazing, but im having trouble when I embed a form into the Draggable Element, all input elements are disabled, any ideas how to disable it?