Motion Design in React.js with “React Motion”

import {Motion, spring} from 'react-motion';

// In your render:
<Motion defaultStyle={{x: 0}} style={{x: spring(10)}}>
  {value => <div>{value.x}</div>}
</Motion>

This library provides an alternative, more powerful API for React’s TransitionGroup. For 95% of use-cases of animating components, we don’t have to resort to using hard-coded easing curves and duration. Set up a stiffness and damping for your UI element, and let the magic of physics take care of the rest. This way, you don’t have to worry about petty situations such as interrupted animation behavior. It also greatly simplifies the API.

Here’s a talk by the author on React Motion:

React Motion →

Motion Design in React.js: UI Animations with CSSTransitionGroup and TransitionGroup

react-animations-disabled react-animations-enabled
React Interface without (left) and with (right) animations

In this article, I am going to use the official components from React.js addons. There are other components/libraries that are better for the job but at the end of the article you will get a good amount of React.js animation practice to better understand these other components.

First the CSSTransitionGroup is covered:

const List = ({items, onRemoveItem}) => {
  const listItems = items.map((item, idx) => {
    return <ListItem key={item} onClick={onRemoveItem.bind(this, idx)}/>
  })

  return (
    <div className="list">
      <CSSTransitionGroup transitionName="list__item-" transitionEnterTimeout={500} transitionLeaveTimeout={500}>
        {listItems}
      </CSSTransitionGroup>
    </div>
  )
}
@keyframes add-item {
  from { transform: scale(0, 0); }
  75% { transform: scale(1.1, 1.1); }
  to { transform: scale(1, 1); }
}
@keyframes remove-item {
  from { transform: scale(1, 1); }
  25% { transform: scale(1.1, 1.1); }
  to { transform: scale(0, 0); }
}

.list__item--enter {
  animation-name: add-item;
  animation-duration: 500ms;
}
.list__item--leave {
  background: #bf4a3c;
  animation-name: remove-item;
  animation-duration: 520ms;
}

Once you get the gist of CSSTransitionGroup, the move to the underlying TransitionGroup (which gives you more control, yet is more “raw” in use) is easy

Improve React.js apps with Motion Design →
Improve React.js apps with Motion Design Source (GitHub) →

ScrollMe – A jQuery plugin for adding simple scrolling effects to web pages

<div class="scrollme">
    <div
        class="animateme"
        data-when="enter"
        data-from="0.5"
        data-to="0"
        data-opacity="0"
        data-translatex="-200"
        data-rotatez="90"
    >
        Yup, that's all.
    </div>
</div>

ScrollMe is a jQuery plugin for adding simple scrolling effects to web pages. As you scroll down the page ScrollMe can scale, rotate, translate and change the opacity of elements on the page. It’s easy to set up and not a single line of javascript is required.

Must say I do like the fact that the data-when attribute accepts enter (= when the element enters the viewport), exit (= when the element exits the viewport), and span (= as long as the element is shown in the current viewport) as a value.

ScrollMe →

scrollReveal.js – Easily reveal elements as they enter the viewport

<div data-sr="enter left please, and hustle 20px"> Foo </div>
<div data-sr="wait 2.5s and then ease-in-out 100px"> Bar </div>
<div data-sr="enter bottom and scale up 20% over 2s"> Baz </div>

<script src='/js/scrollReveal.min.js'></script>
<script>
  window.sr = new scrollReveal();
</script>

Just add data-sr to an element, and it will reveal as it enters the viewport. The data-sr attribute is waiting for you to describe the type of animation you want. It’s as simple as using a few keywords and natural language.

scrollReveal.js →

Related: the aforementioned Skrollr allows you to define CSS changes linked to the current scroll position. It doesn’t use natural language, but allows you to manipulate each CSS property individually. Must say I prefer that way of working more.

Keynote does Material Design

Google’s “Material Design” recreated using Keynote. Wasn’t even aware of the “magic move” effect Keynote sports. The .key file itself can be downloaded right here.

Note: Ever since last year we’ve been seeing quite a lot of these type of animations being sported on websites. Be it animations linked on the current scroll position, animations triggered at a specific scroll position, or interfaces that transition from one state to the other. Recent developments such as velocity.js are accelerating the spread of motion design on the web, yet – still – I’m eagerly awaiting the (very powerful) Web Animations API. Luckily a Web Animations Polyfill already exists.

CSS Animated Content Switching

A trend I’m seeing for the coming year is the rise of Transitional Interfaces on the web. A fine example is the aforementioned Fluidbox, or this interface (extract from the post linked):

0-IoFehxuS6xBU4HMz

Sparked by the post linked — which you should read — I started goofing around with CSS transforms and transitions a bit. The result is something I call CSS Animated Content Switching, which you could use when switching content in tabs or something like that. A little demonstration is embedded in the pen below:

Check out this Pen!

Panels can enter and exit using several animation classes I’ve prepared: a panel can slide in/out to a given direction (up/down/left/right), scale up/down, and/or fade in/out. Just define the animations to use on the wrapper using data-* attributes and you’re good to go:

<div class="panelWrapper" data-enter="slideright" data-exit="slideright">…</div>

Animations can run in parallel, or sequential. Parallel is useful when the entering and exiting panel animate in the same direction (e.g. slide in and out to the right), resulting in one fluid animation. Sequential is useful when the entering and exiting animation are the opposite of eachother.

<div class="panelWrapper" data-enter="slideright" data-exit="slideleft" data-sequential="true">…</div>

Above that some animations can be combined as they’re essentially classnames that are assigned. When scaling up/down it is suggested to also change the opacity along with that, using the predefined fade classname.

The clever aspect of the code is the animating classname: only when the wrapper element has that classname assigned will the CSS properties (transforms, opacity, etc.) of the children be transitioned from a starting position/state to an end position/state. This allows us to set starting positions without any transition, and then – once .animating is in place – transition to the end position. Using onTransitionEnd Using a JavaScript setTimeout (as Firefox has trouble consistently firing the onTransitionEnd event), the state of the animated panels is then updated, awaiting another animation.

Did this help you out? Please consider making a donation:

Skrollr – CSS animations linked to scroll position

Having seen a few single-page year in review minisites the past few weeks, it’s clear that Skrollr has become the de facto standard to implement parallax scrolling effects into your websites.

The idea behind Skrollr is straightforward: link a target CSS property+value to a given scroll position, via data-* attributes:

<div id="example" data-0="width:100%;" data-1500="width:0%;"></div>

Skrollr will interpolate between the start and end value whilst you scroll.

Note that the resulting effect is different from the previously mentioned Scroll Animations. Whereas Scroll Animations triggers an effect when an elements scroll into view (and it cannot be undone once it was started), Skrollr is tightly linked to the actual scroll position/offset: scrolling up will revert the animation.

A really neat (and CPU intensive) example is Flat Design vs. Realism.

flat-design-vs-realism

The folks over a Pingdom have created a little helper function, which they’ve used in their year in review page, to define all values via JavaScript. The essence of the function is this (simplified version of their code):

var setSkrollr = function($el, data) {
    for (var i = 0, l = data.length; i < l; i++) { // loop all data entries (scroll positions + css property & value)
        var d = data[i], // the current data entry
            px = d[0]; // the scroll position (in pixels)
            css = d[1]; // the css property + value to set
        $el.attr('data-' + px, css);
    }
}

Usage is as follows:

setSkrollr($('#example'), [[0, 'width:100%'], [1500, 'width:0%']]);
setSkrollr($('#example2'), [[0, 'transform:translateY(-100%)'], [1500, 'transform:translateY(100%)']]);

I've knocked up a quick demo on codepen:

Check out this Pen!

The key part is position: fixed on all elements to prevent them from scrolling offscreen whilst you scroll. If you don't want to do this, you could wrap all elements into one wrapper div with position: fixed applied to it:

Check out this Pen!

A nice and simple example to get some more inspiration from is this Christmas-themed page.

xmas

Skrollr →
Flat Design vs. Realism →
Pingdom: 2013 – year in review →
Merry Xmas Demo →

Related: The aforementioned Scrollorama does about the same

Did this help you out? Like what you see?
Consider donating.

I don't run ads on my blog nor do I do this for profit. A donation however would always put a smile on my face though. Thanks!

☕️ Buy me a Coffee ($3)