Michæl Graves

Groundskeeper @ gskinner.

Google, Adobe, gskinner | Flutter Interact ’19

Flutter is a mobile UI toolkit that combines fast development, expressive and beautiful UIs, with native performance. To test-drive the platform, Grant Skinner & Mike Chambers recently built Redrix: a mobile companion app for Destiny 2.

Download Redrix on iOS or Android

In the short time since, in preparation for Flutter Interact ‘19, we’ve been collaborating with Google & Adobe to showcase the capabilities and potential of the platform.

With an open brief from Google, we were given the freedom to create expressive experiences with the purpose of inspiring and empowering designers and developers to explore the capabilities of Flutter and learn how easy it can be to elevate UI.

We created 17 distinct vignettes spanning a range of UI concepts and styles targeting different devices and screen sizes. They’re all released open-source (under the permissive MIT license) on our dedicated vignettes showcase website.


We established some high-level goals for the vignettes:

  • real-world: representative of pragmatic & relatable scenarios for apps (with an occasional fun, novel piece sprinkled in)
  • approachable: simple enough to help creators get started quickly
  • delightful: thoughtful & fun motion, interactions, and design

After dedicating time to charge up our own inspiration — researching the most beautiful interactive designs we’ve seen — we compiled a list of ideas, rough sketches and descriptions for potential vignettes.

We reviewed and prioritized the ones that would best achieve our goals. Our designers started working on visual language, illustrations, interactive models, and motion design prototypes.

In parallel, our dev team started building Flutter widgets: modular, re-usable elements used across numerous vignettes for common tasks, such as masking, sprite sequences, and simple 3D rendering. These serve as take-aways for developers to utilize in their own Flutter projects.

We set guidelines for design & development: the architecture and code for all the vignettes should feel like a single, cohesive, and approachable unit. We favored readability over optimization; simplicity over intricacy.

As our vignettes came to life, we earmarked time to share, critique, and prioritize. These sessions informed our iterations & effort, weighed against our timelines.

Near Real-Time Iteration

Hot-reload in Flutter is a game-changer for productive iteration — our design team could critique & communicate concepts, tweaks, and polish to developers to make changes right before their eyes: no recompiling, no deploying a new build for review. No wasted cycles.

We even performed critiques and applied real-time feedback remotely through screen-sharing. The feedback loop almost disappeared; designers and developers working in unison, applying discrete talents towards the same goal simultaneously.

We’re a bit smitten with hot-reload in Flutter.

It’s a testament to the Flutter team, that despite our ambitious vision for the vignettes, our biggest challenge was a familiar one — timelines.

XD to Flutter Plugin

To create our Flutter vignettes, all the UI was hand-coded.

If you’ve poked around our blog for the past 17 years (!) you know we have a long history of building tools, utilities, and workflow enhancements for Adobe products.

As such, we are incredibly excited to be working with the Adobe XD team on their integration with Flutter.

The goal is to empower creators to use familiar design and layout tools & workflows in Adobe XD, and generate Dart code to use in their Flutter apps — streamlining designer and developer collaboration to go from idea, to prototype, to working product, faster.

Leveraging a fairly complex view in Redrix, we re-created the design in Adobe XD, which is exported as a near pixel-perfect view in Flutter. It additionally offers functionality to export elements as re-usable Flutter widgets, complete with configurable instance parameters.

Paired with hot reload, you can make design changes in Adobe XD, and see them instantly reflected in Flutter on a simulator or device.

In 2020, we plan to continue helping Adobe to evolve this tool and release an open-source XD plugin.

If there are specific features or functionality you’d love to see, leave a comment and we’ll add it to the wishlist. You can sign up for early access here.

A Mental Model for Media Queries

Handling layout changes across a broad landscape of devices and browsers typically involves the use of media queries, which enable layouts to bend and flex based on their viewing environment.

Most queries I see are built around the concept of width:

@media screen and (max-width: 640px) {
    body { background-color: blue; }

I love the simplicity of this methodology. It’s straightforward, easy to implement, and it works with content that comprises most websites. But what about web-based apps, the website’s younger cousin? Is this model the most effective media query strategy that can help us with the unique challenges of designing web applications? Continue reading →

Spelling Plus Library Open Sourced

We would like to let everyone know that Spelling Plus Library (aka SPL), our Flash/Flex spell-checking library has been released open source.

We first released SPL as a commercial component over 6 years ago, with a major overhaul to support the Text Layout Framework almost 4 years later. It was always our goal to provide a high quality, performant, and feature rich product, backed by great support. As the requirements of the industry have shifted, and the demand for Flash components has dropped, we felt it was a great time to release it to the community at large.

The entire SPL repository is now available under an MIT license, meaning it is free to use for everyone, including on commercial projects. This includes:

  • The SPL source code. Word list loader and parser, text highlighter, and spelling suggestion and replacement utilities
  • The Flex-based AIR application that helps create, modify, and export word lists
  • All examples, spikes we used for testing, and some internal demos
  • The build process to export Flash and Flex SWCs
  • Generated word lists using custom compression for US and UK English, along with tested word lists for Spanish, French, and German.

You can check out the GitHub repository to get everything. Feel free to submit pull requests. Please note that we are no longer supporting SPL, so any questions or issues reported may not get immediate responses.

Thanks to our supporters over the years, we are super proud of what SPL has accomplished, and hope that it will continue to see life moving forward.

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:


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.

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.