Animations For Your Ionic App with Move.js Last update: 2015-02-06

Animations For Your Ionic App with Move.js

Apps not just live from a large amount of functions and options they provide (although this is most of the time recommended), but to a big amount the live from the user experience. Designing a great user experience can be quite challenging, so this time I want to show you how to make your app more alive by adding some cool animations.

For this we will use the lightweight animation framework Move.js to easily get our Ionic app moving!

Setup a simple App

We start with a blank Ionic app and add the iOS platform, so go ahead with this:

ionic start devdactic-moveit blank
cd devdactic-moveit
ionic platform add ios

Apparently, we can’t install the lib via bower so this time download the master from the github repository and copy the move.min.js from the archive into the www/lib/move/ folder (you need to create the folder).

Good job, now is everything ready to get moved inside our app!

Making some great looking animations

We start with some buttons which will start our animations. Additionally we already set some id’s on our elements as we need to access them from code later in our controller. Finally we include our move.js file before the end of our body. Replace everything inside your <body> with this:

<body ng-app="starter">
	<ion-pane>
		<ion-header-bar class="bar-stable" id="header">
			<h1 class="title">Move it!</h1>
		</ion-header-bar>
		<ion-content class="has-header" id="contentBG" ng-controller="AppCtrl">
			<div id="buttons">
				<button class="button button-full button-stable" ng-click="animateVisuals()">
					Content
				</button>
				<button class="button button-full button-stable" ng-click="moveButtons()">Move me</button>
				<button class="button button-full button-stable" ng-click="blink()">Blink</button>
				<button class="button button-full button-stable" ng-click="timer()">Timer</button>
			</div>

			<div
				style="width: 100%; background-color:#E0F2F1; height: 50px; margin-top: 70%; text-align: center; font-size: 40px; line-height: 100%;"
				ng-cloak
			>
				<div id="myTimer">{{time}}</div>
			</div>
		</ion-content>
	</ion-pane>
	<script src="lib/move/move.min.js"></script>
</body>

So here we got just 4 buttons assigned to some functions, nothing special. Let’s do the magic inside our app.js file:

.controller('AppCtrl', function($scope) {
    $scope.moveButtons = function() {
        var buttons = document.getElementById('buttons');

        move(buttons)
        .ease('in-out')
        .y(200)
        .duration('0.5s')
        .end();
    };
});

Our first function is very simple: We want to move our buttons a bit down the screen. To start an animation with move.js we must get our DOM element, so we get it the angular way through document.getElementById(). Now we can call the move library with our element and specify some actions and properties for the animation. Here we will move the y to y+200, in a duration of 0.5 seconds with a in-out animation which just slows down to the end of the animation.

That’s all for the first tiny animation! You can already have a look at it in your browser/device/simulator, but let’s go on with the next animation.

Next we are going to change the appearance of our app a bit, so add this function to our AppCtrl:

$scope.animateVisuals = function() {
	var bg = document.getElementById('contentBG');
	var header = document.getElementById('header');
	move(bg)
	.set('padding', '10%')
	.duration('2s')
	.end(function() {
		move(header)
		.set('background-color', '#4DB6AC')
		.duration('2s')
		.end();
	});
};

This time we get our Header bar and the content element of our app. First, we set the padding of the complete view to 10% in 2 seconds, and if it’s done we change the background color of our header bar. This is an example on how to perform an animation when the first one is done. Pretty cool, huh?

Next we will make a blink animation, so add the next function to the AppCtrl:

$scope.blink = function() {
	var bg = document.getElementById('contentBG');

	var highlightBack = move(bg)
	.set('background', '#FFFFFF')
	.duration('0.2s')
	.end();

	var highlight = move(bg)
	.set('background', '#B9F6CA')
	.duration('0.2s')
	.then(highlightBack)
	.end();
};

This little animation will change the color of our background and then() change it back so it will look like a blinking whatever. This is another way of chaining animations with move.js. You can define pieces of animations wherever you want and call them in another animation to chain them together. Again, this is so lightweight and elegant, it’s real funny to play with it!

If you want more of cool user experience, check out my Simple Patterlock Login Tutorial

You can play with the values or animations now as our 3 functions are ready. But if you want more, here is a tiny really helpful example you might want to include in your next awesome game!

Making a Timer with Animations

We will now make a simple timer which can be used for e.g. measuring the duration of a game. Therefore we need to add a new div below our buttons div inside our index.html and another button to start the timer inside the buttons div so go ahead with this:

 <div id='buttons'>
     ...
     <button class="button button-full button-stable" ng-click="timer()">Timer</button>
</div>

<div style="width: 100%; background-color:#E0F2F1;
  height: 50px; margin-top: 70%;
  text-align: center; font-size: 40px;
  line-height: 100%;" ng-cloak>

   <div id="myTimer">{{time}}</div>
</div>

Here we have the timer button plus a div which holds our timer. The styling inside the html is not really good style, but for this tiny example I guess it’s ok. I added the ng-cloak so users don’t see a blinking {{time}} on App startup.

Now we just need to add some logic to our AppCtrl, start with adding the $timeout to our dependencies:

.controller('AppCtrl', function($scope, $timeout) {

Next we implement the function which is called from the button:

$scope.timer = function() {
	if($scope.timerTimeout) {
		$timeout.cancel($scope.timerTimeout);
	}
	$scope.time = 0;
	$scope.timerTimeout = $timeout(onTimerTimeout,0);
};

If our timer is already running, we just cancel the action to prevent ugly behaviour. After that we set our timer value to 0 and start our onTimerTimeout() function…which is obviously not yet added, so insert the function now:

function onTimerTimeout(){
	$scope.time++;
	var timer = document.getElementById('myTimer');

	move(timer)
	.ease('snap')
	.set('opacity', 1)
	.scale(1.4)
	.duration('0s')
	.end();

	move(timer)
	.ease('out')
	.x(150)
	.rotate(140)
	.scale(.1)
	.set('opacity', 0)
	.duration('1s')
	.end();
	$scope.timerTimeout = $timeout(onTimerTimeout,1000);
};

A bit of code, but no magic inside. Initially we just increase our timer value and get the timer div element. The first animation ‘snaps’ the number label to an 1.4 scaled size and sets the opacity (back) to 1, as our second animation fades out the element. Additionally, the second animation moves, rotates, scales and sets the opacity in one animation, everything in just a handful of lines. Thats what I call easy! In the end we just set our timer to call the function again in 1 second.

Thats our beautiful animated timer!

Conclusion

This tutorial explained the use of move.js, a lightweight animation framework for JavaScript inside an Ionic app. To view all possibilities regarding chaining your animations or more methods, take a look at the examples or just try out which modification or animation curves matches your expectations. Although the framework might seem very simple, there are many things you can do with it if you just try and experiment with it!

If this tutorial was helpful, follow me on twitter @schlimmson and leave a comment/ tweet it! Don’t forget to subscribe to my newsletter to receive new posts and infos via mail!

See a video version of this article below!

So long, Simon