Saving a Canvas element as an image

Here’s a little tip to allow your users download the contents of a canvas element as an image, without the need for a server. We can do this by using an Anchor tag with a download attribute.

Start with creating <canvas> and <a> tags:

<canvas id="mycanvas"></canvas>
<a href="#" download="MyImage.png" id="downloadlink">Save canvas</a>

The <a> tag’s download attribute can be set to a file name that will be used when saving the file. If no value is specified, it will just be called Download.png.

READ MORE

Paint stencilling with HTML5 canvas

I have recently been playing around with re-writing my Spray paint stencils in Flash using JavaScript and HTML5’s canvas element. One thing I discovered is that since SVGs are natively supported in browsers I can have stencils scaled to any size and remain crisp, unlike the Flash version which used transparent PNGs.

I have implemented stencils, including having a muck layer, and stickers – graphics that you can place and cut out through stencils. When I first started playing around I was writing it all plain JavaScript, but eventually I converted everything over to TypeScript which allowed me to easily separate everything out into their own classes with event listening/dispatching capabilities. Almost mimicking the way things were written in AS3.

Below is a video of the early prototype, I will provide a live demo when it is more ready for public use.

Javascript voice control

Since Chrome 25 we have had access to the new Web Speech API which allows us to create web apps that can utilse voice to text or voice control with a microphone. I have been wanting to experiment with this for quite a while so I built simple example to using voice commands to control an e-learning module made with my e-learning framework. I recorded a video below demonstrating navigation through voice commands. After the video I will show show you how easy it is to set up this basic control.

The following link provides a tutorial on implementing a speech to text example: http://updates.html5rocks.com/2013/01/Voice-Driven-Web-Apps-Introduction-to-the-Web-Speech-API

To use speech recognition for voice commands, this is how I implemented it:

1. Create a new speech recognition object

var recognition = new webkitSpeechRecognition();

2. Make the object continuously check the microphone

recognition.continuous = true;

3. Set the language to use. By default it will use the document’s language

recognition.lang = "en-AU";

4. Start the speech recognition

recognition.start();

5. Get results on the ‘onresult’ event

recognition.onresult = function (e) {
  // loop through the results
  for (var i = e.resultIndex; i &lt; e.results.length; ++i) {
    // only get the final results 
    if (e.results[i].isFinal) { 
      // trim any whitespace from result and pass to our command handler 
      // note: I am using jQuery here to trim the string because my e-learning demo already had jQuery included
      runCommand($.trim((e.results[i][0].transcript).toLowerCase())); 
    } 
  } 
};

6. Set up a function to handle the commands

function runCommand(command){ 
  switch (command) { 
    case "alert" : alert("Hello"); break; 
    case "prompt" : prompt("Enter some text"); break; 
    case "confirm" : confirm("Confirm?"); break; 
  }
}

Reverse engineering Captivate for HTML5 widgets

Adobe Captivate is pretty horrible, especially the HTML5 output. I feel like I’m banging my head against a wall every time I use it. The HTML5 output is riddled with bugs and most of the features simply don’t work. If there is one upside to the HTML5 publishing though (and there aren’t many), it’s the ability to access almost anything in the Captivate movie due to the openness of JavaScript and work around its frustrations. I thought I would document a couple issues I faced which could potentially help someone else out. If you’re trying to figure out how to create a HTML5 widget then see my post on Creating HTML5 widgets for Adobe Captivate 6/7.

Problem 1: Create a custom slide index widget

This is pretty much impossible in the Flash publish. I needed a widget that would automatically get all the slide labels and generate an index. After a bit of digging thanks to Chrome’s dev tools, I discovered that most slide information can be found in the ‘toc’ global object on main Captivate window.

Below is a snippet of code that can be used in the HTML5 widget to get all slide names:

var mainWindow = window.parent; // get captivate main window, widgets are loaded into an iframe

// get list of slides
var slides = mainWindow.toc.mainMovie.stage.slides;

// get slide labels
var i = 0, lgt = slides.length;
for (i; i < lgt; ++i){
  // log all slide labels to the console, you could add them to your custom menu
  console.log( mainWindow.toc.movieProperties[slides[i]].lb );
}

Problem 2: Setting variables doesn’t work properly

Another bug I found in Captivate HTML5 widgets was sometimes setting a variable on the varHandle object doesn’t trigger a change in the movie, such as the cpCmndGotoSlide variable, which tells the movie to go to a particular slide. I found the following snippet to work more reliably:

// use the main movie's executeAction to set the variable
mainWindow.toc.mainMovie.executeAction("cpCmndGotoSlide = 2"]); // go to slide 3

I hope someone else will find this useful.

A new blog design

PurpleSquirrels has gone responsive. I have just flicked the switch on the new PurpleSquirrels design. The new design – which I have been working on over the last few weeks – is now responsive which will make it much easier to read content on mobile devices as it adapts to smaller screens. I had been wanting to make the blog responsive for quite a while but just hadn’t been able to find the time. I contemplated adding it onto the existing design but I decided it would be more beneficial to redesign the whole blog to make it much simpler.

The previous design used a large ‘hero’ image for the first post on the home page. I have taken this idea and refined it in the new version. Now all posts get a large image on the home page and on single post pages.

Visitors using Chrome will notice the use of blurred images at the top of each page which make the blog header reflect the current post. The blurring has been done using CSS filters so no server side scripts are needed and no extra images are downloaded. Browsers that don’t support it will just see un-blurred images. I quite like the effect – blurred or not – of having every page take on it’s own personality depending on what post you are reading.

One thing I have been taking advantage of a lot lately is the use of the :before and :after pseudo elements to create non-rectangular shapes and so I wanted to include this technique in the redesign. All the angular elements such as the purple post date ribbon and the angular post image have been created using purely in CSS using pseudo elements and borders. No images required!

In fact the only images used in the blog template is the PurpleSquirrels logo (a long version and a short version). The logo is an SVG so it should appear nicely on all devices.

On the single post pages I have added next post and previous post buttons which stick to the sides of the screen. They appear as just arrows and slide out when you mouse over them. They have been created purely from CSS.

The final major change is the slide down header that appears once you scroll past the main header, this allows you to access the menu and home page without having to scroll back to the top.

I have also dropped support for IE8 and below – supporting older browsers severely restricts the use of new technologies and I believe holding on to the past just prevents the web from moving forward. If we keep supporting old browsers then where’s the incentive to upgrade, right?

I hope you like the new design. It gave me a chance to utilise some new techniques I’ve learnt, some of which I wouldn’t get a chance to use in client work.

Webcam to canvas or data URI with HTML5 and Javascript

This post has been sitting around unfinished since April so I thought I should finish it and get it out there.

In this post I am going to show how you can capture an image from a webcam via JavaScript and convert it to a Data URI which can then be saved in a database or displayed in an IMG tag.

Note: This is more of a proof of concept rather than a best practices example so the code is a bit messy and hacked together from various sources.

I have only tested this on Safari for iOS 6 and latest Chrome with a webcam. It may or may no work in other browsers.

View demo

All explanations for the the code and markup are in the code comments, so please read them for more detail.

READ MORE

Creating HTML5 widgets for Adobe Captivate 6/7

I decided to write this post due to the frustration and lack of information out there on how to make HTML5 widgets for Adobe Captivate. There is almost no documentation on this and the only useful article I could find was riddled with mistakes. My approach may not be the best but this should get you started.

First things first, you will need to make two versions of your widget – a SWF version and a HTML5 version. Even if you don’t plan on using the SWF version, it is required during authortime in Captivate and is where you can provide the edit mode GUI.

These two versions are packaged up into a .wdgt file which is just a zip file with the extension changed to wdgt.

READ MORE

Windows 8 start screen in HTML, CSS and Javascript

About 7 or 8 months ago I built a tile based launch page at work to launch learning modules which looked similar to the Windows 8 start screen. When I had spare time I kept building on and adding 3D animations to match it even closer to Windows 8. Then I kind of forgot about it until this week when I stumbled upon this article Creating Windows-8-like 3D animations with CSS3 and jQuery which provides a tutorial on creating a similar effect.

I had been meaning to do a post on my laucher when I first started making it but it never happened. So now that that article reminded me I thought I should post it. I am not going to provide any explanations of the code or tutorials but rather just show a demo (It’s HTML and javascript so you can just view the source anyway). I have ripped a bunch of LMS related code out of it and turned it into a web page launcher.

Click a tile to launch an ‘app’ (in this case a website). Hover you mouse over the top or bottom right corner for the ‘charms’ bar to close the site and return to the start screen. I have currently only tested it in Chrome and on an iPad and there isn’t a way to get to the charms bar on iPad yet.

Click to launch demo

JS Transform Handles

The other day I was playing around with Mozilla’s Popcorn Maker and I had the idea of using HTML/JS/CSS to create transformable divs using transform handles and a bounding box. I did a quick search for any existing examples of HTML transform handles but i couldn’t find anything so I decided to give it a go myself. Below is a demo of what I came up with. It might not be the best solution but it works pretty well. I even implemented rotation but I had some issues with the scaling when the element was rotated. The demo has the rotation disabled but you can get the source by view the source of the frame. All JS, and CSS is in the one HTML file. Enabling the rotation is as simple as removing display none from the rotation handles CSS style.

The main reason I wanted to create transformable DIVs is for the next version of my Module Builder. I had experimented with transforming HTML via the AIR app but I think doing it directly in the HTML page.

Leveraging iOS hardware via the browser with Javascript

Just another quick post tonight. I have bigger one lined up for tomorrow I promise. I just wanted to show a little experiment I did a while back with JavaScript – accessing the Accelerometer and Compass data in Safari on the iPad. Below is a short video demonstrating it if you don’t have access to an iPad. If you do have one – visit the link following the video. I might also mention that the arrow/circle image was all created using CSS3 too!

And here’s the link to the demo.

To get the source – just go to the above link and right click > view source.