Orbit Button Glow

Maybe you’ve seen this type of interaction already if you’ve taken a glance at Polymer’s paper components. The idea is that when a click event is triggered an orb like glow appears and then vanishes at the end of the event. It’s a nice and subtle way to provide user feedback when they interact with an element on your page, but also doesn’t break layout if it sits next to other items. We achieve the effect through the use of keyframe animations, class toggling with JavaScript and using the animationend listener made available via JavaScript.

See the Pen Orbit Button by Dennis Gaebel (@grayghostvisuals) on CodePen.

We first setup the keyframe animation which is just a basic box-shadow like so…

@keyframes orbitGlow {
  0% {
    box-shadow: 0 0 0 25px transparent;
  }

  50% {
    box-shadow: 0 0 0 50px rgba(maroon, .10);
  }

  100% {
    box-shadow: 0 0 0 75px transparent;
  }
}

Now that we’ve made an expanding box shadow that disappears at the 100% mark, its time to add this animation to our ‘active’ class in Sass.

.button {
  &.active {
    .js & {
      animation: 600ms orbitGlow forwards ease-in-out;
    }
  }

  &:active {
    .no-js & {
      animation: 600ms orbitGlow forwards ease-in-out;
    }
  }
}

As you can see we’ve given our button a keyframe animation expanding the box-shadow plus adding the animation call to the active class. Notice I’ve also used a .js class to say when JavaScript is enabled trigger the active class, but if JS is disabled just use the :active pseudo class selector. Now it’s time to make the magic happen by adding in a few event listeners to make this interaction come to life.

Our first JS handler is simply saying when an event of it’s type is triggered (i.e. click, touchstart) add the ‘active’ class to the button element…

function buttonGlow(event, cname) {
    event.preventDefault();
    $(this).addClass(cname);
}

$btn.on('click', function() {
    buttonGlow.call(this, event, state);
});

$btn.on('touchstart', function() {
    buttonGlow.call(this, event, state);
});

Our second JS handler is removing that ‘active’ class we’ve added from the initial event…

function buttonGlowEnd(event, cname) {
  $(this).removeClass(cname);
}

$btn.on('animationend', function() {
  buttonGlowEnd.call(this, event, state);
});

Since we’re adding a class name that triggers the animation we need a way to remove that class when the animation ends so the event can be triggered on subsequent clicks/touches. We do this by listening to the animationend event (including our vendor prefixes) supplied to authors via JavaScript. This alleviates us trying to manipulate and time everything correctly for the class removal using something like setTimeOut().

And there you have it. A nice orbit glow that is great for user feedback as well as performant by leveraging the GPU for hardware acceleration and animation. Got a better way to implement this? Hit me up on twitter.

Dennis Gaebel

Design Technologist passionate for Open Source, SVG, Typography, Web Animation, Interaction Development & Pattern Based Design. http://droidpinkman.io.

Leave a Reply

Your email address will not be published. Required fields are marked *

show formatting examples
<pre class="language-[markup | sass | css | php | javascript | ruby | clike | bash]"><code>
…code example goes here…
</code></pre>

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comment Preview

  1. John Doe shouted this comment preview:
    2014/07/02