Create your account

Already have an account? Login here

Note: By joining, you will receive periodic emails from Coursetro. You can unsubscribe from these emails.

Create account

Create an Animated App Onboarding Process with Ionic 3

By Gary simon - Jun 17, 2017

When a user installs your app, sometimes it's necessary to inform them about what your app does and how to use it. With Ionic, you can create a slide-based onboarding process with relative ease.

We're going to take it a step further and even integrate slide-based animations that really look awesome.

So, if you're ready to learn, let's get started!

If you prefer to watch video..

Be sure to Subscribe to the Official Coursetro Youtube Channel for more awesome videos.


You're going to need Node.js with NPM (Node Package Manager) installed. Visit to download and install both of these utilities. NPM is installed by default.

After Node is installed, you will need to install the Ionic CLI. The following command will do just that:

> npm install -g ionic@latest

Once all is ready to go, we're ready to install the project.

Starting the Ionic Project

At the command line, wherever you install your projects type:

> ionic start onboarding blank

This starts a new project called onboarding and uses the blank starter template.

It will download all of the necessary dependencies and install them. This process, of course, takes a minute or two.

Once complete, we'll hop into the new folder:

> cd onboarding

Let's generate a new page with the CLI, which will serve as the main UI after the onboarding process if finished (we won't work within this page at all):

> ionic g page main

Let's serve the project to the browser, with live-reloading and everything ready to go:

> ionic serve -l


Building the Slides

Ionic makes starting the slides very easy by using ion-slides and individual ion-slide elements.

In the /src/pages/home/home.html template file, specify

  <ion-slides pager>





In the lab, you can now click and drag between these slides, or click on the circle navigation at the bottom. pager adds the navigation. 

This is ugly, so let's give it some HTML.

Change the 3 ion-slide elements to the following, and add the button just before the closing ion-content tag:

      <div class="diag" style="background: url('assets/img/whitebg.svg') no-repeat">
        <ion-icon ios="ios-analytics" md="md-analytics" color="primary"></ion-icon>
        <h2>track your routine</h2>
        <p>whether it's sets, reps, weight used, you can track it all with our intuitive interface.</p>

      <div class="diag" style="background: url('assets/img/whitebg.svg') no-repeat">
        <ion-icon ios="ios-trophy" md="md-trophy" color="primary"></ion-icon>
        <h2>set personal goals</h2>
        <p>we're all in the gym for a reason: goals. set goals for diet and fitness.</p>

      <div class="diag" style="background: url('assets/img/whitebg.svg') no-repeat">
        <ion-icon ios="ios-chatboxes" md="md-chatboxes" color="primary"></ion-icon>
        <h2>chat with others</h2>
        <p>inspire and help each other reach fitness and diet goals.</p>

  <button (click)="skip()" id="skip">{{ skipMsg }}</button>

Download the project file (right click and save file as) which is whitebg.svg referenced above. Place it in the /src/assets folder (create a folder inside assets called img which is where the file goes.

The skip button won't appear because we're using interpolation on a property that doesn't exist yet, but don't worry, we'll fix that later.

As-is, the result is still ugly. We need to give it some style.

Styling the Slides

Visit /src/app/app.scss to define a couple global rulesets:

@import url(',700');

ion-content {
    background-color: #EFEFEF !important;

This imports a font called Raleway, and then sets our background color to a light gray.

Let's also change the primary color variable in the /src/theme/variables.scss file:

$colors: (
  primary:    #C400FF,

Then, let's visit the /src/home/home.scss file and place:

.diag {
  position: absolute;
  z-index: 1;
  top: 0;

ion-icon {
    margin-top: 40%;

h2 {
    margin-top:80% !important;

p {
    margin: 0 auto;

.swiper-pagination-bullet-active {

.swiper-pagination {
    bottom: 12% !important;

#skip {
    bottom: 20px;
    background:none !important;

If you save it, the result now should look much, much better in the browser (or your phone):

 If you swipe between the slides, you can see they now work.

Making the Skip Button Work

Right now, the skip text isn't showing because we didn't define a property. We also need to make it direct to our MainPage we created with the CLI on click.

First, MainPage needs to be added to the /src/app/app.module.ts file:

// Import it at the top
import { MainPage } from '../pages/main/main';

// Add it to declarations and entryComponents of NgModule()
  declarations: [
    MainPage  // Here
  entryComponents: [
    MainPage  // And here

  // Other properties removed for brevity

In the /src/pages/home/home.ts file, at the top we have to import the MainPage:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { MainPage } from '../main/main';

Then, in the class section at the bottom:

export class HomePage {

  skipMsg: string = "Skip";

  constructor(public navCtrl: NavController) {


  skip() {


If you save the file, the skip message will be displayed and it will work if you click on it.

Detecting Slide Change

Ionic gives us methods that we can use when the slide is interacted with. For instance, let's say we want to change the Skip message to Alright, I got it at the very last slide.

First, in home.html we change at the top <ion-slides pager to:

<ion-slides pager (ionSlideDidChange)="slideChanged()">

This will call a slideChanged() method when the slide has changed. 

Then, in the home.ts file's import section, we add:

import { ViewChild } from '@angular/core';
import { Slides } from 'ionic-angular';

And in the class section:

export class HomePage {
  @ViewChild(Slides) slides: Slides;
  skipMsg: string = "Skip";

  constructor(public navCtrl: NavController) {


  skip() {

  slideChanged() {
    if (this.slides.isEnd())
      this.skipMsg = "Alright, I got it";


We define a ViewChild and create the slideChanged() method. .isEnd() detects whether or not we have reached the last slide, and if so, we change the skipMsg property to a different string.

Integrating Animation

Adding touch-based animations to your onboarding process adds a little something extra to your app. It makes it fun to use and it's impressive if you do it correctly.

To use animations, we first have to install the animations package at the command line. Before we do that, visit the /package.json file and take note of the version number for @angular/core -- Mine happens to be 4.1.3 .

If serve is currently running in your console, hit ctrl-c and y to end the serve command, and then type:

> npm install @angular/animations@4.1.3 --save

Change 4.1.3 based on your current version number. If you don't use the correct version number, it may result in errors.

Next, we have to make some adjustments in the /src/app/app.module.ts file:

// Other imports
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

// Add BrowserAnimationsModule to imports

imports: [

Now that animation has been configured, let's add animation to our slides.

Adding Animation to the Slides

In the home.ts file, change the top import line to:

import { Component, trigger, transition, style, state, animate, keyframes } from '@angular/core';

This imports all of the animation-specific functions to our component.

Next, we'll add the animations property to the component decorator and define an animation:

  selector: 'page-home',
  templateUrl: 'home.html',
  animations: [
  trigger('bounce', [
        state('*', style({
            transform: 'translateX(0)'
        transition('* => rightSwipe', animate('700ms ease-out', keyframes([
          style({transform: 'translateX(0)', offset: 0}),
          style({transform: 'translateX(-65px)',  offset: 0.3}),
          style({transform: 'translateX(0)',     offset: 1.0})
        transition('* => leftSwipe', animate('700ms ease-out', keyframes([
          style({transform: 'translateX(0)', offset: 0}),
          style({transform: 'translateX(65px)',  offset: 0.3}),
          style({transform: 'translateX(0)',     offset: 1.0})

We define an animation called bounce and set a state to any with *. The transition will activate from any state to rightSwipe or leftSwipe, and we're using keyframes to bounce on the X axis.

Next, in the component class we add:

  state: string = 'x';

  slideMoved() {
    if (this.slides.getActiveIndex() >= this.slides.getPreviousIndex()) 
      this.state = 'rightSwipe';
      this.state = 'leftSwipe';

  animationDone() {
    this.state = 'x';

We define a state property which we set to any value initially.

slideMoved() will be called when we attach another input of ionSlideDrag to the ion-slides element in the template. When called, we use an if statement to check whether or not a user is swiping a slide right or left. .getActiveIndex() is a method that tells us the current slide index number, and .getPreviousIndex() will obviously let us know the previous slide index. So, we can use this if statement to determine whether or not one is swiping left or right based on comparing the index numbers.

animationDone() is called when we attach an event binding of .done to one of the animated elements in the template. Let's do that now.

In home.html update the ion-slides element:

  <ion-slides pager (ionSlideDidChange)="slideChanged()" (ionSlideDrag)="slideMoved()">

And then, we attach [@bounce]='state' to the icon and the div that contains our h2 and p elements in all 3 of the ion-slide elements.

Only for this first instance of the ion-icon do we need to attach (@bounce.done), this will allow us to reset the state variable to a value other than rightSwipe and leftSwipe.

The first one will look like this:

      <div class="diag" style="background: url('assets/img/whitebg.svg') no-repeat">
        <ion-icon ios="ios-analytics" md="md-analytics" color="primary" [@bounce]='state' (@bounce.done)="animationDone($event)"></ion-icon>
      <div [@bounce]='state'>
        <h2>track your routine</h2>
        <p>whether it's sets, reps, weight used, you can track it all with our intuitive interface.</p>

You can repeat that process for the other 2 slides and you will be all set!


If you save the project now, you should have touch-based animation applied to your slides, which makes for a really cool and responsive effect. 

Hopefully, you were able to learn a lot in this tutorial!

Share this post

Say something about this awesome post!