Grant Skinner

The "g" in gskinner. Also the "skinner".

@gskinner

Disable Local Security Errors in Chrome

I’m blogging this mainly for my own benefit, so I can look it up easily whenever I need to:

If you’d like to disable security errors generated from accessing local content in Chrome (ex. reading pixels from a local image), just launch it with the “–disable-web-security” param. So on OSX, you’d type this into Terminal:

open /Applications/Google\ Chrome.app –args -disable-web-security

It lasts until you close Chrome. Handy for testing EaselJS content on your local file system.

Update: I’ve posted a .command file that you can double click in the Finder to run this more easily here.

The Evolution of (Web) Development Tools

I’ve seen a few people complaining about and/or questioning the lack of mature tools to develop content for the modern web (aka HTML5), and it got me thinking about the evolution of these tools, and how challenges are solved for technology platforms in general.

In my (albeit limited) experience, there is a natural progression for a maturing technology stack, particularly one without a single master (ex. Flash and iOS development differ somewhat because the tools and platform are directed/developed by the same entity).

First, you will see the development of a lot of frameworks, starting with micro-libraries that address a single challenge, and evolving to macro-frameworks like JQuery that tackle an entire workflow. Developing frameworks has a very low barrier to entry, and provides an ideal way for developers to explore and share a variety of potential solutions for challenges. Because the libraries are written in the domain language, it also means that any developer encountering a problem can address it directly with a language they are familiar with.

As problems become better defined, and specific solutions begin to emerge as more dominant, you start to see single purpose tools created, often as command-line utilities. These have an increased investment compared to frameworks, and require that the developer has knowledge of both the problem domain, and basic desktop development.

Next, you will see partial workflow tools, which aggregate and leverage the single purpose tools (either directly, or by borrowing approaches). These put a UI on top of a number of solutions to make them more accessible to users. Again, these involve increased investment, and require additional capability (UX/UI design, more advanced desktop development).

Finally, you will see the emergence of full-scale workflow tools. These represent a major investment, generally require a team of specialists to create, and are built over the course of months or years. As such, they need to build on top of standards, approaches, and frameworks that have been well vetted by real-world use. Even then, their early releases will be limited, and will require a huge amount of community feedback and multiple revisions to “get it right”. With this in mind, early release with rapid iteration is a critical practice for any tool that aims to be successful in this space.

As an aside, code editors tend to follow an accelerated path, simply because the problems they are solving are less tied to a specific technology platform, and have been thoroughly explored for other languages.

Of course, none of these steps happen in isolation. In the JS world, you can see all of these underway simultaneously. There is an unending stream of new frameworks, as developers explore challenges, with a number of more mature ones gaining traction. There are a number of popular single-purpose tools (ex. LESS, Closure Compiler, Zoë). There are a few partial workflow tools (ex. CodeKit). And finally, there are a number of early entries in the more robust tool category (Edge, Sencha Animator, Flash Pro’s Wallaby, etc).

Further, this evolution is massively complicated and slowed in the HTML/JS world by the constant flux of the technology, the non-trivial issue of supporting multiple browsers/platforms, and the question of legacy support. Tool makers need to wait for a standard (or more frequently, a collection of standards) to stabilize and be broadly adopted/accepted before they can risk the investment to build on top of it.

This is obviously a simplified look at the problem, but hopefully helps illustrate where things are today, and why we don’t have access to fully mature tools for HTML5 development yet. They are coming, but it’s going to be an incremental process.

Updates to EaselJS, SoundJS, TweenJS & Zoë!

I’m very happy to announce that I’ve pushed major updates to a number of our javascript tools and libraries for developing rich content with HTML5. It’s very exciting for me to see these starting to realize some of the vision I’ve had for them over the past year, both as individual pieces and as a suite of tools to make great interactive content using web standards.

Here’s a quick breakdown of what was released:

EaselJS v0.4.0
The latest release of EaselJS (our HTML5 display library) has a completely reengineered sprite sheet engine, which includes a host of new features: multi-image sprite sheets, variable frame dimensions, frame reuse, image preloading, and a new data format. Note that this change will require some minor updates to existing content using sprite sheets in EaselJS.

We’ve added filter effects, and a few sample filters, including a box blur filter by Mario Klingemann, who has agreed to write a number of other filters for the library.

There’s also a fantastic new build system, built on top of Node.js by Adobe’s own Mike Chambers. And, of course, a whole pile of other feature additions, optimizations and bug fixes. Check the VERSIONS file for full details.

Zoë v1.5.0
We’ve released a major update to Zoë, our tool for exporting sprite sheets from SWF animations. It supports EaselJS’s new data format, and adds some great new features like variable frame dimensions with more optimal rect packing, and intelligent frame reuse. The latter allows you to set a threshold for how similar frames can be, and Zoë will automatically remove similar frames and reuse them in animations. Testing on some old content, we saved 20-50% on file size with this feature, with virtually no decrease in animation quality.

This release was a bit more rushed than we would have liked, so you should expect to see a v1.5.1 release before too long that polishes things up and adds additional features such as multi-image export.

TweenJS v0.1.0
This is the first “official” release of TweenJS. TweenJS uses a simple API of chained commands to sequence tweens and actions to create complex animations and timed events. For example:

Tween.get(ball).to({x:200},500).wait(750).to({alpha:0,visible:false}).call(onComplete);

TweenJS makes a great companion to EaselJS, and also has some basic support for working with CSS properties, which will be extended in future versions.

SoundJS v0.1.0
This is also the first official release of SoundJS, our library for working with the HTML5 Audio tag. Sound in HTML5 is a complete mess to work with, and this library aims to make it a bit easier. It handles preloading, allows you to assign a fixed number of tags to a specific sound, provides volume control, and manages sound interruption.

This library is still a little rough, but we’re planning to continue to clean it up and add functionality (ex. WebAudio support) as time permits.

in summary
All of these projects are free and open source, released under the highly permissive MIT license, and are hosted on GitHub. I’d like to thank everyone who contributed to these releases, even if just by providing feedback or encouragement. Hopefully people find these useful in their own quests to build amazing content for the web!

As an aside, now that these releases are out of the way, I’m considering doing a series of posts or videos on getting started with some of these libraries. I think it would be particularly relevant as Flash developers start looking to create content in HTML5, and web developers look to create more interactive content.

TweenJS: Animate, Tween & Sequence in Javascript

There were a lot of requests for tweening support in EaselJS, so to address this I thought I’d try writing a companion tweening library. I started in on this a couple days ago, and just posted the very early results to a new GitHub repo.

This is very much pre-alpha, untested, undocumented, and subject to change, but I thought I’d share it and solicit feedback.

It has a simple but powerful API that uses chained method calls to create complex tweens (similar to Graphics in EaselJS). For example, the following code will create a new tween instance that tweens the target’s x value to 300 for 400ms, waits 500 ms, then tweens the target’s alpha to 0 over 1s, sets its visible to false, and calls the onComplete function.

var myTween = Tween.get(myTarget).to({x:300},400).wait(500).to({alpha:0},1000).set({visible:false}).call(onComplete);

You can also use it to sequence commands, without tweening at all:

var mySeq = Tween.get(target).call(doStuff,[param]).wait(500).set({prop:value}).set({prop:value},foo).call(allDone);

Let me know what you think. We’re still considering whether it should live completely on its own, or be a part of EaselJS. Right now it has no dependencies on EaselJS, but it will use the same Ticker class if available. It should work to tween / sequence just about anything in Javascript, but so far I’ve only tested it with EaselJS and HTML5 canvas.

You can check out an example of TweenJS in action here. Have a look at the source code to get a better sense of how things work.

You can grab the library from the TweenJS GitHub Repo.

Music Visualizer in HTML5 / JS with Source Code

It’s no secret that I like building music visualizers, or that I’ve been playing with HTML5 a fair amount lately. Given that, I thought I’d combine the two interests, and build a music visualizer using JS, the canvas & audio elements in HTML5, and the EaselJS framework.

The primary challenge was that Javascript doesn’t have any built in mechanism for accessing the volume of a playing audio tag. To address this I wrote a little AIR application that will read an MP3 file using Sound.extract() and export peak volume data as a text or JPG image file. I then wrote a JS class called VolumeData.js that reads in these files and provides access to the data via a simple interface (ex. myVolumeData.getVolume(time) ).

With those pieces in place and tested, I started putting together a demo of it in action using EaselJS. Two of the newest features were compositeOperation support (which let me approximate an “add” blend mode), and the drawPolyStar method, both of which I used to excess.

I think the end result is pretty cool, though it requires a fairly modern system, and will still melt your CPU – I was intentionally pushing things hard to try to find the performance limit. It requires an up to date browser to run.

I built two variations: Star Field and Atomic. Occasionally dynamic audio loading seems to break on certain browsers, just reload if it gets stuck on “loading music”.

If you’re interested in building your own music visualizers in HTML5/ Javascript, you can download the demo source, VolumeData.js class (MIT licensed) and VolumeData AIR application here. Also, be sure to check out the latest version of EaselJS (we just released v0.3.2 today).

Please let me know if you build anything cool with the code. I’d love to see it.

EaselJS v0.3.2 Released

I’m happy to announce the release of EaselJS v0.3.2. It provides a few new interaction features, cleans up the docs, and fixes some known issues. Here’s the full list:

– added stage.mouseInBounds
– added DisplayObject.onMouseOver and onMouseOut callbacks
– added stage.enableMouseOver(freq)
– improved support for calculating mouseX/Y in divs with relative positioning
– fixed Graphics.clone()
– fixed an issue with shadows not being reset properly
– migrated to use YUIDocs instead of JSDocs
– fixed an issue that prevented BitmapSequence instances with frameData from working with gotoAndPlay(frameNumber)

I’d like to thank everyone who contributed by providing bug reports, feedback, and edits. In particular I would like to thank Mike Chambers (of Adobe fame) for all his fantastic help on EaselJS. He has been an invaluable resource for bouncing ideas off, providing a critical second perspective, and helping with code / doc edits.

As always, you can get more info and grab the latest zip from easeljs.com, or check it out on the EaselJS GitHub repository.

We’re currently finalizing plans for v0.4 (which looks to be a very aggressive undertaking), and would love any feedback or ideas you can provide here or on GitHub.

Zoë: Export SWF Animation as EaselJS SpriteSheets

Alongside the release of EaselJS v0.3 we’re also releasing the first version of Zoë, a free Adobe AIR application for exporting SWF animations as sprite sheets (single images containing a grid of animation cells), including frame data for use with EaselJS.

This means you can use Flash Pro to lay out your animations then very easily prep them for use with EaselJS and the HTML5 canvas element.

We used an early version of Zoë to prep all of the animations for the Pirates Love Daisies game we released a few weeks ago, which let our illustration team work with a tool they felt comfortable with, using tweens, skeleton constraints, and graphic symbols.

Here’s a quick feature overview:

  • Exports a single sprite sheet image, or individual frames
  • Reads frame labels in the swf to generate frame data.
  • Writes frame data as JSON or EaselJS files
  • Calculates the frame dimensions automatically based on the animation content
  • Saves profiles to make it easy to re-export when art changes

And a screenshot:

You can grab Zoë from easeljs.com/zoe.html. It’s currently not open source, but we’ll likely release the source once we have a chance to fix any major issues that arise with the public release and clean up the code.

EaselJS v0.3 Released!

I’m very happy to announce that version 0.3 of EaselJS has been released. Even better, it’s now on GitHub, so you can fork it to your hearts content.

This version makes it even easier to build compelling content using the HTML5 canvas element and javascript. It has a rewritten rendering engine with support for skewing, an improved and optimized interaction model (5-10x faster), and a slew of other new features and fixes. Here’s the whole list, in no particular order:

  • renamed Tick to Ticker
  • adding a listener to Ticker twice will now move it to the end of the listener list
  • added Ticker.getMeasuredFPS()
  • added Ticker.setFPS()
  • renamed Stage.tick to Stage.update and made Stage.tick point to Stage.update
  • made the pauseable param “true” by default on Ticker.addListener()
  • added Stage.toDataURL(backgroundColor, mimeType)
  • renamed Rectangle.w/h to width/height
  • improvements to commenting and documentation
  • formalized inheritance model to make code more readable
  • changed color to null instead of 0 in Shadow.IDENTITY
  • fixed an error with simple sprite sheets that weren’t set to loop
  • implemented “tiny” instructions for Graphics. (ex. myGraphics.f(“#0FF”).c(x,y,r) )
  • fixed problems with Graphics.clone()
  • fixed bug with passing instructions to a Graphics object constructor
  • complete rewrite of the render engine to be cleaner and more flexible
  • added .decompose() method to Matrix2D
  • added .skew() method to Matrix2D
  • added .skewX/Y on DisplayObject
  • added SpriteSheetUtils.extractFrame(spriteSheet,frame) method
  • added basic multi-line support for Text
  • added DisplayObject.suppressCrossDomainErrors property
  • complete rewrite of the hit testing system to be cleaner and run 5-10x faster
  • improved the interaction model:
    • added .onPress, .onClick callbacks on DisplayObject
    • removed .mouseChildren from Container
    • made .mouseEnabled true by default
    • added .onMouseDown, .onMouseUp, and .onMouseMove callbacks on Stage
    • added MouseEvent
  • Stage.getObjectsUnderPoint() has been moved to Container
  • added Container.contains(child) method
  • added DisplayObject.compositeOperation
  • added appendProperties() and prependProperties methods to Matrix2D
  • added DisplayObject.hitTest() method
  • added stage.snapToPixelEnabled and displayObject.snapToPixel
  • added DisplayObject.updateCache()
  • renamed minified file from easeljs.js to easel.js
  • Re-factored directory layout

Check out EaselJS.com for more info or to grab the latest build.