Elastic SVG Elements

Some inspiration for elastic components with SVG shape animations for enhanced UI interactions.
Morphing Shape Effects

From our weekly sponsor: Design every part of your website with the brand new Divi Theme Builder. Try it for free.

Today we’d like to share some inspiration for adding elasticity to elements. The idea is to integrate an SVG element into a component and then animate it from one path to another with an elastic animation. Using SVGs like this can make things like menus, buttons or other elements more interesting and make the interaction look more organic with a natural feel to it. It’s of course important to keep things subtle and not exaggerate the bounciness. The nice thing is that we can give a more “realistic” interaction feedback to the user. Especially touch feedback can benefit from using this kind of effect. Based on this idea, we’ve created some inspirational examples of contexts where a morphing shape animation enhancement could make sense.

For animating the SVGs, we use Snap.svg, the excellent JavaScript SVG library for modern browsers.

The icons used in some of the demos are from the one and only Font Awesome icon set by Dave Gandy.

For the demo with the draggable & droppable elements we use Dragabilly by David DeSandro.

Please note that this is highly experimental and the demos were only tested in the latest versions of modern browsers.

An example of how we use the SVGs in the components (the sidebar menu in this case) is the following:

<nav id="menu" class="menu">
	<button class="menu__handle"><span>Menu</span></button>
	<div class="menu__inner">
		<ul>
			<li><a href="#"><i class="fa fa-fw fa-home"></i><span>Home<span></a></li>
			<li><a href="#"><i class="fa fa-fw fa-heart"></i><span>Favs<span></a></li>
			<li><a href="#"><i class="fa fa-fw fa-folder"></i><span>Files<span></a></li>
			<li><a href="#"><i class="fa fa-fw fa-tachometer"></i><span>Stats<span></a></li>
		</ul>
	</div>
	<div class="morph-shape" data-morph-open="M300-10c0,0,295,164,295,410c0,232-295,410-295,410" data-morph-close="M300-10C300-10,5,154,5,400c0,232,295,410,295,410">
		<svg width="100%" height="100%" viewBox="0 0 600 800" preserveAspectRatio="none">
			<path fill="none" d="M300-10c0,0,0,164,0,410c0,232,0,410,0,410"/>
		</svg>
	</div>
</nav>

The SVG is inserted after the inner menu and we use two data attributes to store the paths we will be animating the default path to (depending on whether we open or close the menu).

The SVG will be placed absolute into the menu, and enough spacing needs to be ensured on the sides so that we see the line moving elastically without getting cut off. Note that the SVGs are made responsive by using a width and height of 100% and not preserving the aspect ratio. This is important for some shapes as you might want to retain certain proportions and allow a stretching in one dimension only. For this example, although we always set the width and height to 100% in the HTML, we set a fixed width to the morph shape wrapper and the SVG:

.morph-shape {
	position: absolute;
	width: 240px;
	height: 100%;
	top: 0;
	right: 0;
}

.morph-shape svg path {
	stroke: #5f656f;
	stroke-width: 5px;
}

With Snap.svg we can then morph from one shape to another:

(function() {

	function SVGMenu( el, options ) {
		this.el = el;
		this.init();
	}

	SVGMenu.prototype.init = function() {
		this.trigger = this.el.querySelector( 'button.menu__handle' );
		this.shapeEl = this.el.querySelector( 'div.morph-shape' );

		var s = Snap( this.shapeEl.querySelector( 'svg' ) );
		this.pathEl = s.select( 'path' );
		this.paths = {
			reset : this.pathEl.attr( 'd' ),
			open : this.shapeEl.getAttribute( 'data-morph-open' ),
			close : this.shapeEl.getAttribute( 'data-morph-close' )
		};

		this.isOpen = false;

		this.initEvents();
	};

	SVGMenu.prototype.initEvents = function() {
		this.trigger.addEventListener( 'click', this.toggle.bind(this) );
	};

	SVGMenu.prototype.toggle = function() {
		var self = this;

		if( this.isOpen ) {
			classie.remove( self.el, 'menu--anim' );
			setTimeout( function() { classie.remove( self.el, 'menu--open' );	}, 250 );
		}
		else {
			classie.add( self.el, 'menu--anim' );
			setTimeout( function() { classie.add( self.el, 'menu--open' );	}, 250 );
		}
		this.pathEl.stop().animate( { 'path' : this.isOpen ? this.paths.close : this.paths.open }, 350, mina.easeout, function() {
			self.pathEl.stop().animate( { 'path' : self.paths.reset }, 800, mina.elastic );
		} );
		
		this.isOpen = !this.isOpen;
	};

	new SVGMenu( document.getElementById( 'menu' ) );

})();

With the right easing functions and appropriate timings, a slightly bouncy, organic movement can be created. But the options are so versatile and depend on the whole feel of a specific context, so the possibilities are endless 🙂

We hope you enjoy these little effects and find them inspiring!

Tagged with:

Mary Lou

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

http://www.codrops.com

Stay up to date with the latest web design and development news and relevant updates from Codrops.

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start learning CSS now.

Feedback 38

Comments are closed.
  1. Wow, Great Elastic Effect. Esp i love that Dropdown and Bottom Menu Elastic thing. Planning to implement in my future projects. 🙂

  2. So cool !!

    I absolutely love the EXPAND

    One thing I noticed was on the INPUTS demo the effect only comes in when the user clicks into the field, not if they tab in. I’ve certainly found that one you click into the first form field one tends to just tab through, so it would be nice to add that in.

    I’m on Safari 8.0.

  3. Really amazing stuff, was wondering what the IE support is if anyone knows, I don’t have my VM’s setup is it IE9 or IE10+ ?

  4. Hi. I really love it. But I need put the ‘Sidebar Menu’ in the left side. Is complicated? What values I need modify? I greatly appreciate the any willing to help. Thanks!

  5. Incredible effects! Very timely inspiration for a school website I’m working on. I wonder though, how would I be able to try some of these examples while still giving the best possible experience to users with older browsers?

  6. great! together with semantic abilities, light weight we can construct fluid responsive interfaces. Awesome future!

  7. Yes, I freaking love how awesome this is. Just finished reading Five agency’s article on how they’re thinking about incorporating Google’s Material Design, so this was the perfect follow-up. Can’t wait to test this out. Thanks Mary Lou!

  8. Is there any legal problem or something if I use those designs in a official web page?
    Do I need to name this site or can I just use them without any problem?

  9. It looks awesome but it seems i dont have the brain to modiy any of it. Even simple things like changing icons to the ones i have.

    The other sidebar you made is amazing as well – Google nexus.

    Step 1 for me was to change icons in the drop down menu … failed 🙁
    Step 2 was to try and make an image appear next to the item in menu when hovering over that item .. failed again

    sigh