Category Archives: HTML5

PhoneGap Exploration – Realtime Hardware Communication

Recently I’ve undertaken some explorations with fellow evangelist Kevin Hoyt, trying to determine how far we can push PhoneGap applications with devices and physical computing. Turns out, you can push things really far and now I’m delighted to share one of the experiments that we’ve been pursuing.

I’ve been asked on more than one occasion, can you access Bluetooth devices in PhoneGap applications. The answer is YES, you can. There is not a specific “Bluetooth API” in PhoneGap, however you can create native plugins to access any native library. Basically, with a native plugin, you create the native interface (written in the native language), and a JavaScript interface. The native and JavaScript interfaces can leverage the PhoneGap native to JavaScript bridge for bidirectional communication.

In this exploration, we researched whether or not you can use a pressure sensitive stylus with a PhoneGap application. Again, the answer is YES, you can. Check out the video below to see a sample application in-action. This example demonstrates the use of a TenOne Pogo Connect Stylus inside of a PhoneGap application.

Note: This is not connected to Project Mighty in any way – Kevin and I started exploring completely separately from the big announcements at MAX.

The Pogo Connect stylus leverages Bluetooth 4 Smart (low energy) connectivity to communicate with the device, and provides pressure sensitivity and a physical button for the user to interact with. The JavaScript interface doesn’t interact directly with with the Bluetooth connection. Instead, I leveraged TenOne’s Pogo Connect SDK and created a JavaScript bridge layer to delegate pen interaction from the SDK to the JavaScript layer.

There were definitely a few tricks to get this working. First, the SDK is designed to accept touch input at the native layer, and determine whether or not that touch is from the pen. When using the SDK (in Objective-c), you are supposed to implement the touchesBegan, touchesMoved, touchesEnded, and touchesCancelled functions for a view:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

In those functions, you check if any of the touches are pens, and if so, do something with that pen input.

- (void) touchesBegan: (NSSet *)touches withEvent:(UIEvent *)event {
	for (UITouch *touch in touches) {
		if ([pogoManager touchIsPen:touch]) {
			//do something with the pen
		}
	}
}

The first catch with implementing this inside of a PhoneGap application is that you can’t override the touch handlers of a web view on iOS. Luckily, there is another way! I leveraged a UIGestureRecognizer instance to intercept the touch input that is received by the web view, determine if the touches were from the PogoConnect Stylus, and if so, then delegate that input back to the JS layer.

UIGestureRecognizer is normally used as a base class for creating custom gestures in iOS applications. If has everything you need to handle touch input, and it gives you that information without having to subclass an actual view. This means you can attach it to any UIView instance. Since you don’t have to subclass a view to use this, this plugin can be implemented in a PhoneGap native plugin without having to modify *any* code inside the PhoneGap framework.

So, here’s how I did it… Once the PhoneGap plugin is initialized on load, I create a gesture recognizer instance and attach it to the PhoneGap application’s web view. Whenever touch input is received by the gesture recognizer, that input is passed back to the PhoneGap plugin instance, which executes JavaScript on the web view to pass that information to the JavaScript layer in real time as it is received.

On the JavaScript layer, stylus/pen input is dispatched to the application as custom events on the window.document object. To subscribe to pen input in JavaScript, you just add event listeners for the Pogo Connect events that I defined in the native plugin’s JavaScript file.

document.addEventListener( pogoConnect.PEN_TOUCH_BEGIN, app.penTouchBegin );
document.addEventListener( pogoConnect.PEN_TOUCH_MOVE, app.penTouchMove );
document.addEventListener( pogoConnect.PEN_TOUCH_END, app.penTouchEnd );

Information about the stylus will be contained in the event.detail attribute, and will be an instance of this object (containing accurrate values about the pen’s state, of course):

{
    identifier: 0,
    connected:false,
    x:NaN,
    y:NaN,
    pressure:0,
    buttonDown:false,
    tipDown:false,
    lowBattery:false
}

In JavaScript, you can do whatever you want within your application once you receive this information.

I created two sample applications to test this functionality. The first is a very basic app that simply outputs the pressure as text which follows the pen tip. The intent with this app was really just to prove the concept and determine if it was actually possible to receive and respond to information from the stylus.

Basic Pressure Sensitivity Detection in PhoneGap

Basic Pressure Sensitivity Detection in PhoneGap

Once I proved it could be done, the next logical step was to create an app that actually takes advantage of the pressure sensitivity information. So, I made a sketching app.

Pressure Sensitive Sketching in PhoneGap

Pressure Sensitive Sketching in PhoneGap

I started off by expanding on the drawing logic from my Lil’ Doodle PhoneGap application. This uses a requestAnimationFrame interval to render content in an HTML Canvas element using a “brush image” technique. Next, I added logic to vary the opacity and stroke size based on the pressure information received from the pen plugin, and a few other options to change the pen tip/brush shape and color.

The pressure sensitive stylus gives a few interesting interactions that you wouldn’t get without the hardware:

  • First, the obvious, you know the pressure being applied to the pen tip, and the app can respond accordingly.
  • Next, you have an extra input method. The button on the pen allows you to interact with the device without having to actually touch the device. I used the button in two ways: first, if the button is pressed and held, the pen erases instead of draws. Second, if you double-tap the pen button, it brings up the drawing options. These options are where I placed controls to modify the pen color and stroke.
  • Third, the plugin provides bidirectional communication with the Stylus. When you change the pen color, the LED on the pen will display the selected color for a few seconds.

I used a modified version of DevGeeks’ Canvas2Image plugin to save the content of the HTML Canvas to the device’s photo library. I also had to leverage a variation of this technique for getting the data from the Canvas element without transparency.

All button and slider styling leverages Topcoat, Adobe’s brand new open source CSS framework designed to help developers build HTML-based apps with an emphasis on performance.

Full source code for this application is available on GitHub at https://github.com/triceam/PGPogoConnect

Note: This is iOS only – The third-party PogoConnect SDK is for iOS devices only. This example will also ONLY work if you have the PogoConnect Stylus. It does not support other stylus devices or finger-only drawing.

DataVizDC Meetup: Images, Resources & Audio Recording

Last night I had the opportunity to give a presentation on Data Visualization With Web Standards to the DataVizDC meetup group. First of all, I’d like to thank the meetup group for hosting the event, and thank you to everyone who attended – It was a great event thanks to the excitement and energy brought by each of you. I promised to post a video recording, but unfortunately the video feed didn’t turn out (due to an error on my part).  Luckily, I was able to save the audio feed, which you can listen to here:

You can access my presentation slides at the links below.  Just use the “space” key to advance each slide.

You can also view all the associated resources from the presentation at:

Here are just a few images from the event, and you can find more presentation details below:

001 photo-1 photo-2 photo-3

Key Takeaways

Here are links to the Adobe HTML resources I mentioned at the beginning of the presentation.

Here is a direct link to the simple interactive data experience that was created using Adobe Edge Animate (also available for download in the Edge Animate Showcase):

Edge Animate Data Sample

Visualization Techniques

<img>

You can embed images using the html <img> element that have server-rendered data visualizations. This is nothing new… They are very basic, but will certainly work.

  • Not interactive
  • Requires online & round-trip to server
  • No “WOW” factor – let’s face it, they are boring
  • Example: Google Image Charts

HTML5 <canvas>

You can use the HTML5 <canvas> element to programmatically render content based upon data in-memory using JavaScript. The HTML5 Canvas provides you with an API for rendering graphical content via moveTo or lineTo instructions, or by setting individual pixel values manually.  Learn more about the HTML5 canvas from the MDN tutorials.

  • Can be interactive
  • Dynamic – client side rendering with JavaScript
  • Hardware accelerated on some platforms
  • Can work offline
  • Works in newer browsers: http://caniuse.com/#search=canvas

Gun Violence Visualization – Please, let’s not discuss the politics.

HTML5 Canvas Scatterplot with Histogram (50K data points)

HTML5 Canvas Chart – Asteroids Analysis

HTML5 Canvas – Three.js 3D Chart


Scalable Vector Graphics (SVG)

SVG is a declarative XML-based markup language that is used to create vector graphics content, and can be used to create visual content inside of web experiences.

  • Client or Server-side rendering
  • Can be static or dynamic
  • Can be scripted with JS
  • Can be manipulated via HTML DOM
  • Works in newer browsers (but not on Android 2.x and earlier): http://caniuse.com/#search=SVG

SVG – James Bond Visualization

SVG – Sankey Diagrams

SVG – Connected Scatterplots

SVG – Bullet Charts


HTML DOM Elements

Visualizations such as interactive maps, or simple charts can be created purely with HTML structures and creative use of CSS styles to control position, visual presentation, etc… You can use CSS positioning to control x/y placement, and percentage-based width/height to display relative values based upon a range of data. For example, the following bar chart/table is created purely using HTML DIV containers with CSS styles.


WebGL

WebGL is on the “bleeding edge” of interactive graphics & data visualization across the web. WebGL enables hardware-accelerated 3D graphics inside the browser experience. Technically, it is not a standard, and there is varied and/or incomplete support across different browsers (http://caniuse.com/#search=webgl).  There is also considerable debate whether it ever will be a standard; however there are some incredible samples out on the web worth mentioning:

WebGL – Globe w/ Arms Trading Data

WebGL – New Google Maps

WebGL – World Population

WebGL – Sample Visualization (could be used for molecule structure)


Interactive Coding

I also put together several interactive/editable samples for demonstrating basic visualization techniques.  You can preview all of these samples on my Data Visualization Collection on Codepen.io.

Interactive Coding in the Browser on CodePen.io

Interactive Coding in the Browser on CodePen.io

Enjoy!

Getting Started With Adobe Edge Web Fonts

Amongst the big announcements last week, you may not have noticed that the Adobe Edge Web Fonts got a huge upgrade too!  It’s now easier than ever to browse web fonts and include them into your own HTML experiences. All for free, with no Creative Cloud membership required!

Adobe Edge Web Fonts

Adobe Edge Web Fonts

Check out the video below to see the new interface in action:

Also shown in the video is Adobe Edge Code for live editing/previewing HTML in the browser.

Enjoy!

Live Editing Server Files with Edge Code/Brackets

If you haven’t already heard of Adobe Edge Code or Brackets, it is a new HTML/CSS/JS code editor that enables a rapid development cycle by connecting directly to your browser for automatic real-time updates to the HTML content running inside the browser. This promotes rapid development, and allows you to focus on writing your code rather than worrying about all the steps required to switch between your editor and browser and step through development and debugging iterations.

In most contexts we talk about the live HTML/JS/CSS development perspective on the client side, but I’d also like to highlight that Adobe Edge Code and/or Brackets can be used to rapidly develop dynamic server-side web code too. Check out the screencast below to see live editing of dynamically generated HTML content using the latest Brackets release (Sprint 23).

This streamlined workflow can be incredibly powerful, especially for rapid prototyping scenarios. You just focus on writing code and creating an experience. Let the edtior offload the work of updating the live content in your browser to keep you focused on the task at hand.

To enable the Edge Code/Brackets preview on a server, just go into “File->Project Settings”, and then specify a “Preview Base URL” string. The preview base URL will be prefixed to the name of the file that you are editing, and will be used for the browser’s URL in the live connection. So, if you are editing “index.html” with a preview base URL of http://tricedesigns.com, brackets will launch the live connection with the URL “http://tricedesigns.com/index.html”.

However, keep in mind that Edge Code & Brackets’ primary use case is editing HTML/JS/CSS, not server-side languages. The editor won’t have code hinting for your server-side code, unless you are using an extension that enables code hinting (with the exception of NodeJS because JavaScript is supported). The current build of Brackets also changes the live preview URL when you change files. So, if you are editing “index.cfm”, and switch to “content.cfm” in the editor, the live preview will follow, and switch to “http://{urlprefix}/content.cfm”. If the files are intended to be separate, this works great. However, if content.cfm isn’t a standalone file, the live preview won’t be as valuable. Meaning: if content.cfm is actually an included file inside of index.cfm, the live preview of content.cfm may not work the way you want it to. In either case, this can still be a very valuable tool with rapid prototyping.

Speaking of extensions… Edge Code/Brackets is built with an extensible plugin architecture. Since the editor itself and all of the extensions are written with HTML/JS, you can easily extend and customize the tool to add any functionality that you want.

if you’re wondering about the difference between the names Adobe Edge Code and BracketsAdobe Edge Code is Adobe’s distribution of the Brackets editor. Adobe Edge Code has scheduled releases, and includes useful extensions and tie-ins to other Adobe services (for example, Adobe Web Fonts and more). Brackets is the open source project for the core editor itself. Brackets is on a 2-3 week sprint cycle, and is rapidly evolving. Essentially, Brackets is the “engine” that powers Adobe Edge Code.

I chose a simple ColdFusion demonstration because I already had an existing code sample I could reuse, however this will work with PHP, NodeJS, or other server-side scripting libraries. The latest builds of Brackets even have NodeJS built directly into it.

The code that I used in this example is available as a gist for download. This was based on my existing US Census Browser sample PhoneGap application.

Enjoy!

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.