Ionic GO

Ionic GO – Create a Pokémon GO Style Interface in Ionic 2



·

When Pokémon GO was released I was in the middle of the Australian outback – the PokéStops, Gyms, and even the Pokémon were few and far between. Although I was missing out on the action a bit, I knew that it was gaining popularity fast but it wasn’t until I got back to a major city that I saw hordes of people of all ages walking around, not so discreetly flailing their phones around attempting to catch Pokémon.

I think it’s a great concept, and it hits the nostalgia bone hard. It goes without saying that this has been an enormous social phenomenon, and what kind of blogger would I be if I didn’t try to cash in on all of this excitement with some contrived blog post?

Although it is somewhat of a gimmick, one of the most notable features in Pokémon GO is the augmented reality mode, where the user interface and the Pokémon you are trying to catch are overlaid on to the devices camera:

Pokémon GO Screenshot

This gives the sense that your device is a portal into the Pokémon world. Augmented reality can be a lot of fun, like Pokémon GO and Snapchat filters, but also very useful and practical with applications like Planet Finder that overlays the position of planets and stars, or Augmented Car Finder.

In this tutorial we are going to create our own, very simple, example of augmented reality. We will be recreating the Pokémon GO interface above, into something that looks like this:

Ionic GO Screenshot

Unfortunately, we won’t be coding in little bugs for you to catch with your Ionballs, it’ll just be the interface overlaid onto the camera for now.

NOTE: The Cordova plugin that allows us to overlay an interface onto the camera is super cool, and the contributors have done a great job in developing it. It is not currently in a stable state though, and I’ve experienced a few quirks and bugs in developing this example. Keep in mind that this is just intended to be a fun example, I wouldn’t recommend using this for real projects just yet (hopefully that will be a possibility in future though).

Before We Get Started

Before you go through this tutorial, you should have at least a basic understanding of Ionic 2 concepts. You must also already have Ionic 2 set up on your machine.

If you’re not familiar with Ionic 2 already, I’d recommend reading my Ionic 2 Beginners Guide first to get up and running and understand the basic concepts. If you want a much more detailed guide for learning Ionic 2, then take a look at Building Mobile Apps with Ionic 2.

1. Generate a New Ionic 2 Application

Let’s start by generating a new Ionic 2 application. The application is just going to have one screen, and no providers or anything like that, so we are going to just stick with a simple blank application.

Run the following command to generate a new application

ionic start ionic2-go blank --v2

2. Install the Camera Preview Plugin

The camera is a native function of the device, and to interact with Native APIs with Cordova we need to use plugins. One very commonly used plugin is the Camera plugin, which will launch the camera, allow the user to capture an image, and then return that image for us to make use of in the application.

It’s a bit of a black box though – the app makes a call to launch the camera, then the app receives the image data back. There’s not really any way for us to control what happens when the user is interacting with the camera (apart from a few options we can specify when launching the camera). This isn’t of much use to us in creating the Ionic GO interface.

Recently though, I came across the Camera Preview plugin, which allows you to interact with the camera through the HTML interface in your applications. So rather than the camera behaving as some external thing that it is launched on request, with this plugin we can integrate it directly into our application.

Run the following command to install the Camera Preview plugin:

ionic plugin add cordova-plugin-camera-preview

3. Launch the Camera Preview

Now that we have the plugin ready to use, we need to trigger it when the app starts. We will hook into the ready() method in the root component to do this. We will be using the Ionic Native version of this plugin, so we need to make sure that we import it first.

Modify src/app/app.component.ts to reflect the following:

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { CameraPreview } from 'ionic-native';
import { HomePage } from '../pages/home/home';

@Component({
  template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
  rootPage = HomePage;

  constructor(platform: Platform) {
    platform.ready().then(() => {

      StatusBar.styleDefault();
      Splashscreen.hide();

      let tapEnabled: any = false;
      let dragEnabled: any = false;
      let toBack: any = true;
      let alpha = 1;
      let rect: any = {
        x: 0, 
        y: 0, 
        width: platform.width(), 
        height: platform.height()
      };

      CameraPreview.startCamera(
        rect,
        'rear',
        tapEnabled,
        dragEnabled,
        toBack,
        alpha
      );

    });
  }
}

All we’ve done is add a call to the startCamera method of the plugin with some options. Most importantly, we have set toBack to true, which is what sends the camera behind the web view. There’s quite a few options you can supply to the plugin, including allowing the user to take a picture, but I won’t be covering most of those here so make sure to check out the documentation.

Another important thing to take note of is that since we are sending the camera behind the web view, we won’t be able to see it. In order to be able to see the camera behind the web view, we need to make a bunch of elements transparent:

Modify src/app/app.scss to include the following:

html, body, ion-app, ion-content, ion-page, .nav-decor {
  background-color: transparent !important;
}

As you can see we are now making the entire web page transparent, including some of the Ionic elements as well. Now anything we add to our templates will still be visible, but we will be able to see the camera in the background.

4. Create the User Interface

We have everything set up now, so all we have left to do is add the interface. This is as simple as adding to the template file as you usually would. We are going to use some FAB buttons (Floating Action Buttons) to create the interface, which we are able to create in Ionic 2 simply by adding some attributes to a normal button.

Modify src/pages/home/home.html to reflect the following:

<ion-content>

    <div id="ionball"></div>

    <ion-fab right top small>
        <button ion-fab color="light"><ion-icon name="switch"></ion-icon></button>
    </ion-fab>

    <ion-fab left top small>
        <button ion-fab color="light"><ion-icon name="exit"></ion-icon></button>
    </ion-fab>

    <ion-fab right bottom small>
        <button (click)="refresh()" ion-fab color="light"><ion-icon name="archive"></ion-icon></button>
    </ion-fab>

</ion-content>

We have three buttons now: one in the top left, one in the top right, and one in the bottom right. We also have a <div> to hold our “ionball”, which we will be adding shortly.

Also notice that one of these buttons calls the refresh() function, this is to deal with a bug I will talk about in a moment.

Modify home.scss to reflect the following:

page-home {

    #ionball {
        position: absolute;
        bottom: 30px;
        left: calc(50% - 50px);
        width: 100px;
        height: 100px;
        background-image: url(../assets/images/ionball.png);
    }

}

This CSS just handles setting up the “ionball” at the bottom center of the screen. You will of course also need to include that image.

Create a new folder at src/assets/images and add the following image:

ionball

Now let’s deal with that bug I was talking about.

Modify home.ts to reflect the following:

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

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController) {

  }

  refresh(){
    window['location'].reload();
  }

}

The refresh function that is being called from the template (the bottom right button) will now reload the application when it is clicked. I have found that on iOS, the camera won’t display until the application is refreshed. I’m not sure if this is a bug or limitation with the plugin, the browser, or Ionic but I haven’t been able to make it work without first refreshing. If you have any more information on this, please leave a comment!

If you load the application up on your device now (remember, the camera won’t work through the browser), you should have an interface that looks like this:

Ionic GO Screenshot

Summary

This was a bit of a fun and silly example without much of a practical purpose, but I think it demonstrates that there is potential for creating augmented reality applications with Cordova. I’ve always considered augmented reality to be a case for native applications, but if you can overlay an interface on top of the camera then there is plenty you could do with that.

I’d like to investigate this more in the future and see if I can come up with a more “real world” example, but in the mean time it’d be great to see what all of you could come up with. If you do create something, please email me or post in the comments – I’d love to feature some creations in another blog post.

What to watch next...

  • Amr Ayoub

    Great tutorial , i have a question . should we always include the plugin in the app.ts , can’t we make it as a service and inject it anywhere we want ?

    • You can call it wherever you want, I just put it there so it launched right away.

      • Citizen ION

        Hello Josh what are your thoughts on using alpha channel video in a situation like this. Chrome supports its use.

  • I hadn’t seen it before, looks very cool though!

  • I get this error in Xcode : ERROR: Unhandled Promise rejection: undefined is not an object (evaluating ‘cordova.plugins.camerapreview.startCamera’) ; Zone: angular ; Task: Promise.then ; Value: TypeError: undefined is not an object (evaluating ‘cordova.plugins.camerapreview.startCamera’)
    Any thoughts?

    • Are you running this on a real device? It won’t work through the browser and I think this plugin doesn’t work in emulators either.

      • Running on a real device. Copy & paste from your code…
        The buttons shows correctly, but the background is white

      • Have you also run the command to install the plugin: ionic plugin add cordova-plugin-camera-preview ?

      • Yeah of course! So embarrassing 😛 Nice tutorial!

      • Garel Bidi

        Hi @fhasseleid:disqus , @joshmorony:disqus ,
        I’ve the same issue : I can see the buttons but the background is white.
        I’ve copied and pasted the code right.. I don’t understand this bug..
        Have you find a way to fix it ?
        Thanks a lot for your help ! I’m about to buy the ionic Bible !!!!

      • Ben

        I needed to include ion-app in the css that is making the background transparent:

        html, body, ion-app, ion-content, ion-page, .nav-decor {
        background-color: transparent !important;
        }

      • mohcine melloul

        i’ve added .fixed-content to the elements who has to be transparent and it worked for me.

      • Thomas Kientz

        How did you do that ?

      • mohcine melloul

        Just add .fixed-content to this line :

      • Citizen-ION

        Hello Thomas. Were you able to get working

      • Thomas Kientz

        Same. When I deselect and then reselect the rule ‘background-color: transparent !important;’ from the body element it works (from the safari inspector with my iphone plugged in) Weird…

        So the plugin is working fine, its the transparent rule who is having issues

  • john119

    I’m getting similar behavior as described by Fredrik (white background), while running on Ionic View in iOS, and have installed all plugins. Is there an issue with this plugin on Ionic View? The ‘cameratest’ as suggested here: https://github.com/driftyco/ionic-view-issues/issues/79 also does not work for me on Ionic View.

    • The plugin likely isn’t compatible with Ionic View, I know some aren’t, which is why I don’t test with Ionic View (hard to tell if it’s a problem with your code or with Ionic View)

  • Hazou Shebly

    i tried this on note4 android 6.0.1 and each time i tried it just stopped. when i install to the device sometime the screen would appear but with black screen. button are displayed and when i stop and start the app it just won’t start

    • Clemouuche

      Have you tried to give the right to access camera in settings/application/yourapp/permissions ?

  • roberto

    Hi Josh, I don’t know if this is the right place to put the comment about “Building Mobile Apps with Ionic 2”. However, the last release is great improved because there is an index in the pdf and new pub format. Only one very little suggestion… the “code” font and graphic can be improved and rendered similar to code editor as sublime, for relaxed an more clear understanding of the logic. I post an example

  • roberto

    However i’m really satisfied of your book, I’m about 80% to complete the book (and write the first app), then I’ll buy the next package

  • Camera preview plugin, thanks!
    Nice tuto

  • Kévin

    Hi Josh, thanks for amazing tutorial.

    Have you tried to find a fix for the window[‘location’].reload(); ?

  • Thomas Kientz

    Great thanks ! Running an iphone i don’t need to refresh to start the camera (but i’m not using your UI) !

  • Jose

    Hi! I did all parts of the tutorial and after splashscreen hide the app stops. What could be the reason? And I have this on Manifest

  • Philipp Breuss-Schneeweis

    FYI: There is a version of the Wikitude Ionic Plugin for Ionic 2 as a free Starter app in the Ionic Market: https://market.ionic.io/starters/wikitude-ionic-2-starter-app and on Github: https://github.com/pbreuss/wikitude-ionic-2-starter-app
    Cheers,
    Philipp

  • Sergio Talente

    Hi Josh, thanks for this very useful tutorial. I’m trying to adapt it to an app with two pages, but only one of these must activate the camera. I had to remove “transparent” style directive from app.scss because their would be applied to all pages, but I can’t figure out how to make transparent my page only. I’m using Ionic 2 and I tried to style the ion-content in the page .scss file in this way:

    page-camera {

    .cameratrans {
    background-color: transparent !important;
    color: #00F !important;
    }
    }

    having the following .html page file:

    Camera Page

    the blue color is applied to text but the transparent background is not, so I can’t see the camera. Any ideas?

    • apply it to a class, and then trigger that class based on the page you’re on instead.

  • Ryan Pinfield

    I have spent a lot of time working with Ionic v1 and have decided to make the jump to v2. Thank you very much for your tutorials they have been very helpful. I am having an issue though, I’m trying to have a function callback when the user taps on the screen, annoyingly I keep getting the error “Supplied parameters do not match any signature of call target.” The code is as simple as this:

    CameraPreview.setOnPictureTakenHandler(function(result){
    console.log(result);
    });

    Any thoughts?

  • Hanzo

    Work this with Ionic view? I’ve tried to implement this on my app and ran it into my iphone 6 plus and the screen keeps black. If I click on refresh button the apps restart. Any idea?

  • ME_83

    Is it possible to use the Wikitude plugin for free?