Category Archives: Mobile

PhoneGap & Android Studio

Yesterday at GoogleIO, Google announced Android Studio, a new development environment for authoring Android applications. This is a great looking new IDE for Android, based off of IntelliJ IDEA, with some new Android-specific tools and features. You can read more about Android Studio on the Google Android Developers blog.

One of my first tasks upon downloading Android Studio was to get a PhoneGap app up and running in it. Here’s how to get started. Note: I used PhoneGap 2.7 to create a new project with the latest stable release, however you could use the same steps (minus the CLI create) to import an already-existing PhoneGap application. Be sure to backup your existing project before doing so, just in case you have issues (Android Studio is still in beta/preview).

First, follow the PhoneGap “Getting Started” instructions all the way up to (and including) the command line invocation of the “create” script.

01-cmd

Once you have the Java environment configured just run the create script to create a based PhoneGap project. In this case, I used the following command to create a new PhoneGap project:

./create ~/Documents/dev/android_studio_phonegap com.tricedesigns.AndroidStudioPhoneGap AndroidStudioPhoneGap

Next launch Android Studio. When the welcome screen appears, select the “Import Project” option.

02-welcome

Next, you’ll have to select the directory to import. Choose the directory for the PhoneGap project you just created via the command line tools.

03-select existing src

Once you click “OK”, you will proceed through several steps of the import wizard. On the next screen, make sure that “Create project from existing sources” is selected, and click the “Next” button.

04-create from existing src

You will next specify a project name and project location. Make sure that the project location is the same as the location you selected above (and used in the PhoneGap command line tools). I noticed that the default setting was to create a new directory, which you do not want. Once you’ve verified the name and location, click “Next”.

05-project location

On the next step, leave the default settings (everything checked), and click “Next”.

06-import project

Again, leave the default settings (everything checked), and click “Next”.

07-import project

Yet again, leave the default settings (everything checked), and click “Next”.

08-import project

For the last time, leave the default settings (everything checked), and click “Next”. This is the last one!

09-import project

Next, review the frameworks detected. If it looks correct to you, click the “Finish” button.

10-import project

Android Studio should now open the full IDE/editor. You can just double click on a file in the “Project” tree to open it.

11-android_studio

To run the project, you can either go to the “Run” menu and select “Run {project name}”, or click on the “Run” green triangle icon.

12-run

This will launch the application in your configured environment (either emulator or on a device). You can see the new PhoneGap application running in the Android emulator in the screenshot below. If you’d like to change your “Run” configuration profile, go to the “Run” menu and select “Edit Configurations”, and you can create multiple launch configurations, or modify existing launch configurations.

13-running

Adobe MAX Videos Now Available

The keynotes and many of the session videos form Adobe MAX are now available online at tv.adobe.com/show/max-2013/, and are free for everyone to view. Keep in mind, not all videos are up yet, but will be added soon.

Thanks to Ray for sharing on twitter!

The first-day keynote focuses on Adobe’s evolution of Creative Cloud and various product updates. The second day keynote focuses upon inspiration – do not miss this one.  I especially liked Erik Johansson and Rob Legatto’s segments.

Day 1 Keynote: A Creative Evolution

About This Episode: The process of where and how we create is dramatically changing thanks to major advancements in technology, and there has never been a more exciting time. Join Adobe CEO Shantanu Narayen, Adobe’s SVP and GM of Digital Media David Wadhwani, and a collection of Adobe visionaries across digital photography, web design, illustration, video and more as we unveil brand new creative workflows and capabilities. We’ll take a look at the present and set our sights on the endless possibilities in our creative future.

Day 2 Keynote: Community Inspires Creativity

About This EpisodeJoin David Wadhwani, Adobe’s SVP and GM of Digital Media, as he welcomes four incredibly creative minds to explore how they foster creativity and approach their work. You will hear from Rob Legato, an Oscar winning visual effects supervisor; Paula Scher, an iconic graphic designer and illustrator; Erik Johansson, an up and coming photographer and retouch artist; and Phil Hansen, a constraint-based artist that believes limitations drive creativity. We think you’ll leave with more than a few new ideas to incorporate in your next creative project.

You can view all Adobe MAX 2013 session recordings online at: http://tv.adobe.com/show/max-2013/ (Keep in mind, not all videos are up yet, but will be added soon).

Update: Videos of MAX Sneaks also available via the Adobe Creative Cloud Youtube Channel.

Enabling Gestures in Edge Animate Compositions

As I mentioned in my last post, I’ve been working a lot lately with Adobe Edge Animate, Adobe InDesign, and Adobe DPS.  Here’s another post on that same subject.

Another request that I have gotten from some of our DPS customers is that they’d like to be able to implement gestures inside of the Edge Animate compositions that they are building for DPS publications. This includes double-tap gestures, swipe gestures, etc… Out of the box, these gestures aren’t supported, but you can add them to any Edge Animate composition without too great of an effort.

Below is a quick video showing Edge Animate Compositions that are taking advantage of both double-tap and swipe gestures.  Note: I intended these to be used inside of DPS, but I show them in Safari on iOS.  These gestures override the default mobile browser behaviors.

As I mentioned above, this isn’t something that is supported out of the box, but it is possible to add gesture features manually.

The links below are for the basic examples that I put in the video.  Both should work in desktop and mobile browsers:

For the double tap example, just perform a double tap/click gesture anywhere on the stage (the image area), and the animation will start again from the beginning.  For the swipe gesture, just perform a horizontal swipe in either direction with either your finger, or the mouse.

Gestures With Hammer.js

I leveraged the hammer.js JavaScript library to handle gesture detection since these gestures aren’t supported by default.  Hammer.js also enables other gestures, like long taps, pinch, rotate, etc…  However, I’m only showing double tap and swipe.  You can read more about hammer.js using the following links:

I used this exact setup procedure in both the double-tap and swipe examples.

To include this library, I first downloaded the hammer.js file, and saved it inside of the “edge_includes” folder.

hammer.js

Next, you have to disable the web view/browser default double tap behavior, which is to zoom in when double tapped.  You can disable the zoom on double tap by adding a viewport metadata tag inside of the Edge Animate project’s html file.  Open your project’s .html file (in this case “DoubleTap.html”, and add the following line to the <head>

<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />

Example:

html

Next, we have to add the code inside of the Edge Animate composition to enable the gesture behavior.  The first thing you have to do is include the hammer.js library.  In this case, I wanted to add the gestures to the composition’s stage, instead of a particular element.  So, right-click on the stage in the Edge Animate Editor, then select  the “Open Actions for Stage” menu option.

open_actions

This will open the actions for the Stage instance.  Next, click on the “+” icon and select “creationcomplete”.  This will create a function that gets invoked once the Stage instance has been created at runtime.

creation_complete

In that function, first we need to import the hammer.js library.  Edge Animate compositions include the yepnope.js library, which is originally intended to detect if a browser includes a specific piece of functionality.  If not, then include a JS library so substitute that missing feature.  In this case, I am passing it a blank test to force it to include the hammer.js library.  The following function forces loading of the hammer.js library.  Once the library has been loaded into memory, it triggers the “init” function:

yepnope1

In the init function, we grab a reference to the stage’s element (div), then use hammer.js to add our gesture event handlers:

yepnope2

Now, we need to start looking at the individual examples…

Double Tap Gestures

In the double tap example, we have a simple timeline animation that plays sequentially.  At the end of the sequence the animation is stopped by a simple sym.stop() function call.  Here’s a quick preview of the setup in Edge Animate:

edge_double_tap

To add the double tap gesture, all you have to do is add a hammer.js event for “doubletap”.  In that event handler, we’re just calling sym.play(0), which restarts playback from the beginning of the composition. The full code for the creationcomplete event is shown below.  This is all that is needed to add the double-tap gesture to the composition stage instance:

yepnope({
	nope:['edge_includes/hammer.js'] ,
	complete: init
});

function init (){

   var element = sym.element[0];
   var hammer = Hammer(element);

   hammer.on("doubletap", function(event) {
        sym.play(0);
   });
}

Swipe Gestures

In the swipe gestures example, we have a simple timeline animation that plays sequentially.  However, at the end of each slide transition, playback is stopped by a simple sym.stop() function call.  Whenever we perform a swipe action, we’re either just playing forward, or playing in reverse until the next slide animation stops.  Here’s a quick preview of the setup in Edge Animate, note the stop points highlighted by the arrows:

edge_swipe

To add the swipe gestures, all you have to do is add a hammer.js event for “swipeleft” or “swiperight”.  In those event handlers, we’re just calling sym.play() or sym.playReverse(), depending whether it was a left or right swipe.  These play actions progress to the next animation sequence. The full code for the creationcomplete event is shown below.  This is all that is needed to add the swipe gesture to the composition stage instance:

yepnope({
	nope:['edge_includes/hammer.js'] ,
	complete: init
});

function init (){

	var element = sym.element[0];
	var hammer = Hammer(element);

	hammer.on("swipeleft", function(event) {
		  sym.play();
	});

	hammer.on("swiperight", function(event) {
		  sym.playReverse();
	});
}

With the swipe gestures, you can get some drag event conflicts on mobile devices.  If you run into this and you do not want the page to scroll, the scroll action can be prevented by capturing the touchstart event, and canceling the default behavior.  I didn’t add this, just because I wanted to keep this example very simple.

Source

Full source for each example can be downloaded from the links below:

Artwork used in these examples is from the Adobe MAX web site.  You should attend MAX, it’s going to be awesome.

Publishing

When you publish the composition from Edge Animate, the “hammer.js” file won’t be copied automatically, so make sure that you copy it to your publish directory before distributing the composition.

PhoneGap Legends – A Sample Game App

Next week I’ll be representing Adobe at GDC 2013, and demonstrating how Adobe Creative CloudPhoneGap, and PhoneGap Build can be great tools for building casual gaming experiences. In preparation, I’ve been working on a gaming sample application that shows off the potential of HTML games packaged with PhoneGap.

…and now I’d like to introduce you to PhoneGap Legends. PhoneGap Legends is a fantasy/RPG themed demo that leverages HTML DOM animation techniques and targets webkit browsers. I was able to get some really outstanding performance out of this example, so be sure to check out the video and read the details below. The name “PhoneGap Legends” doesn’t mean anything; I just thought it sounded videogame-ish and appropriately fitting.

PhoneGap Legends

PhoneGap Legends

This game demo is an infinitely-scrolling top-view RPG themed game that is implemented entirely in HTML, CSS, and JavaScript. There is a scrolling background, enemy characters, HUD overlays, and of course, our “protagonist” hero – all that’s missing is a story, and general game mechanics like interacting with sprites.

Again, I was able to get some *really outstanding performance* out of this sample, so I wanted to share, complete with source code, which you’ll find further in this post (and I encourage you to share it too). Take a look at the video below to see the game in action on a variety of devices. Every single bit of this is rendered completely with HTML, CSS, and JavaScript – there are no native portions of the application.

Update 3/24:  If you’d like to test this out on your own devices, you can now access it online at http://tricedesigns.com/portfolio/phonegap_legends/   However, it will still only work on webkit browsers (Chrome, Safari, Android, iOS, etc…), and is optimized for small-device screens.  If you attempt to use this on a very large screen, you’ll probably see some sprite clipping.

Disclaimer: This sample app is by no means a complete game or complete game engine. I’ve implemented some techniques for achieving great performance within a PhoneGap application with game-themed content, but it still needs additional game mechanics. I also wrote this code in about 2 days – it needs some additional cleanup/optimization before use in a real-world game.

Source

Full source code for this demo application is available on GitHub. This code is provided as-is: https://github.com/triceam/PhoneGap-Legends. I will be making a few updates over the next few days in preparation for GDC next week, but for the most part, it is stable.

Development Approach

The PhoneGap Legends application was built following the performance tips that I posted earlier this month. The game is built so that it uses a game loop based upon requestAnimationFrame to perform all UI updates. This gives it a scheduled interval that is in sequence with the browser’s redraw cycle.

In general, the DOM is as shallow as possible for achieving the desired experience. All “sprites”, or UI elements are basic DOM nodes with a fixed position and size.  All DOM elements have an absolute position at 0,0 and leverage translate3d for their x/y placement.  This is beneficial for 2 reasons: 1) It is hardware accelerated, and 2) there are very, very few reflow operations.  Since all the elements are statically positioned and of a fixed size, browser reflow operations are at an extreme minimum.

The background is made up a series of tiles that are repeated during the walk/movement sequence:

Sprite Sheet for Background Tiles

In the CSS styles, each tile is 256×256 square, with a background style that is defined for each “type” of tile:

.tile{
    width: 256px;
    height:256px;
    overflow: hidden;
    position: absolute;
    top:0px;
    left:0px;
    background-repeat: repeat;
    background-clip:border-box;
}
.tile_0 {      background: url('../images/background_tiles.png');     background-position: 0px 0px;}
.tile_1 {      background: url('../images/background_tiles.png');     background-position: 256px 0px;}
.tile_2 {      background: url('../images/background_tiles.png');     background-position: 512px 0px;}
.tile_3 {      background: url('../images/background_tiles.png');     background-position: 0px 256px;}
.tile_4 {      background: url('../images/background_tiles.png');     background-position: 256px 256px;}

The content displayed within each of the “sprite” DOM elements is applied using sprite sheets and regular CSS background styles. Each sprite sheet contains multiple images, the background for a node is set in CSS, and the position for each image is set using the “background-position” css style.  For example, the walking animation for the hero character is applied just by changing the CSS style that is applied to the “hero” <div> element.

Sprite Sheet for Hero

There is a sequence of CSS styles that are used to define each state within the walking sequence:

.hero_0_0{ background: url('../images/rpg_sprite_walk.png'); background-position:0px 0px;}
.hero_0_1{ background: url('../images/rpg_sprite_walk.png'); background-position:0px 96px;}
.hero_0_2{ background: url('../images/rpg_sprite_walk.png'); background-position:0px 192px;}
.hero_0_3{ background: url('../images/rpg_sprite_walk.png'); background-position:0px 288px;}
...

This game demo extensively uses translate3d for hardware accelerated composition.  However, note that the 3d transforms are all applied to relatively small elements, and are not nested. All of the “textures” are well below the max texture size across all platforms (1024×1024), and since it uses sprite sheets and reusable CSS styles, there are relatively few images to load into memory or upload to the GPU.

Attribution

The following Creative Commons assets were used in the creation of this sample app and the accompanying video:

Image – Grass Texture: http://opengameart.org/content/grass-with-moss
Image - Trees/Bushes: http://opengameart.org/content/lots-of-hyptosis-tiles-organized
Image - Main Character: http://opengameart.org/content/2d-rpg-character-walk-spritesheet
Image - Enemies: http://opengameart.org/content/rpg-enemies-11-dragons
Image - Compass Rose: http://en.wikipedia.org/wiki/File:Compass_rose_en_04p.svg

Font – Avalon Quest: http://www.ffonts.net/Avalon-Quest.font
Note: I used a free/open licensed font that could be embedded in the app for offline usage. This font was converted to a web-font package that can be embedded in the PhoneGap application using http://www.fontsquirrel.com/

Audio – Monster: http://www.freesound.org/people/Erdie/sounds/167890/
Audio – Music: http://www.freesound.org/people/rap2h/sounds/115261/

Source

Again, in case you missed it above, Full source code for this demo application is available on github. This code is provided as-is: https://github.com/triceam/PhoneGap-Legends.

On-Device Debugging With PhoneGap & iOS 6

Want to debug your PhoneGap apps, complete with breakpoints, DOM & CSS inspection, profiling, and more?  This is all possible with the PhoneGap Emulator, which allows you to leverage Chrome’s Developer Tools inside of the desktop Chrome browser (covered in detail here).  However, did you also know that you can have a rich debugging/development experience in an app that is actually running on a device?

Since the release of iOS 6 last Summer, we’ve all had the ability to debug PhoneGap apps while they are running on external iOS devices, or inside of the iOS simulator. I’m surprised how often I hear that people are not aware of this feature. With iOS 6 you can use Safari’s developer Tools to connect to any HTML content on the device, either in the mobile Safari browser, or inside of a web view. PhoneGap apps fall into that second category, they are based upon iOS system web view.

You can check out a preview of remote debugging on iOS in the video below:

In order to take advantage of this, you’ll first have to enable the remote web inspector for Safari on iOS. Just follow the instructions for “Debugging Web Content on iOS” from Apple – be sure not to skip the “Enable Web Inspector on iOS“ section, which is hidden by default.  You have to enable this in iOS Settings in order for the desktop Safari Browser to be able to connect to any web content on the mobile device.

Once enabled, you can lever the full capabilities of Safari’s Developer Tools, including DOM & CSS inspection and modification, JavaScript breakpoints, storage, resources, exceptions, console logging, and more…

webinspector

Unfortunately, this is only available for PhoneGap on iOS devices at this time. Android enables remote debugging inside of the Chrome browser, however that isn’t enabled for PhoneGap apps *yet*.  Whenever Google enables Chrome for web views inside of apps, it’s on!