After 10 years

October 31st, 2014

Yesterday marks 10 days to the day since I posted my first patch to Bugzilla. It was a small patch to composite SVG images with their background (and not just have a white background).

Since then I’ve contributed to Firefox as a volunteer, an intern, a contractor, and, as of 3 years ago tomorrow, a Mozilla Japan employee.

It’s still a thrill and privilege to contribute to Firefox. I’m deeply humbled by the giants I work alongside who support me like I was one of their own. In the evening when I’m tired from the day I still often find myself bursting into a spontaneous prayer of thanks that I get to work on this stuff.

So here are 8 reflections from the last 10 years. It should have been 10 but I ran out of steam.

Why I joined

  1. I got involved with Firefox because, as a Web developer, I wanted to make the Web platform better. Firefox was in a position of influence and anyone could join in. It was open technically and culturally. XPCOM took a little getting used to but everyone was very supportive.

What I learned

  1. Don’t worry about the boundaries. When I first started hacking on SVG code I would be afraid to touch any source file outside /content/svg/content/src (now, thankfully, dom/svg!). When I started on the SVG working group I would think, “we can’t possibly change that, that’s another working group’s spec!” But when Cameron McCormack joined Mozilla I was really impressed how he fearlessly fixed things all over the tree. As I’ve become more familiar and confident with Firefox code and Web specs I’ve stopped worrying about artificial boundaries like folders and working groups and more concerned with fixing things properly.

  2. Blessed are the peacemakers. It’s really easy to get into arguments on the Internet that don’t help anyone. I once heard a colleague consider how Jesus’ teaching applies to the Internet. He suggested that sometimes when someone makes a fool of us on the Internet the best thing is just to leave it and look like a fool. I find that hard to do and don’t do it often, but I’m always glad when I do.

    Earlier this year another colleague impressed me with her very graceful response to Brendan’s appointment to CEO. I thought it was a great example of peace-making.

  3. Nothing is new. I’ve found these words very sobering:

    What has been will be again,
      what has been done will be done again;
      there is nothing new under the sun.
    Is there anything of which one can say,
      “Look! This is something new”?
    It was here already, long ago;
      it was here before our time. (Ecclesiastes 1:9–10)

    It’s so easy to get caught up in some new technology—I got pretty caught up defending SVG Animation (aka SMIL) for a while when I worked on it. Taking a step back though, that new thing has almost invariably been done before in some form, and it will certainly be superseded in my lifetime. In fact, every bit of code I’ve ever written will almost certainly be either rewritten or abandoned altogether within my lifetime.

    In light of that I try to fixate less on each new technology and more on the process: what kind of person was I when I implemented that (now obsolete) feature? What motivated me to work at it each day? That, I believe, is eternal.

How I hope Mozilla will shape up over the next 10 years

  1. I hope we’ll be the most welcoming community on the Web

    I don’t mean that we’ll give free hugs to new contributors, or that we’ll accept any patch that manages to enter Bugzilla, or we’ll entertain any troublemaker who happens upon #developers. Rather, I hope that anyone who wants to help out finds overwhelming encouragement and enthusiasm and without having to sign up to an ideological agenda first. Something like this interaction.

  2. I hope we’ll stay humble

    I’d love to see Mozilla be known as servants of the Web but when things go well there’s always the danger we’ll become arrogant, less welcoming of others’ ideas, and deaf to our critics. I hope we can celebrate our victories while taking a modest view of ourselves. Who knows, maybe our harshest critics will become some of our most valuable contributors.

  3. I hope we’ll talk less, show more

    By building amazing products through the input of thousands of people around the world we can prove Open works, we can prove you don’t need to choose between privacy and convenience. My initial interest in Mozilla was because of its technical excellence and welcoming community. The philosophy came later.

  4. I hope we’ll make less t-shirts

    Can we do, I don’t know, a shirt once in a while? Socks even? Pretty much anything else!

Animations on Fire @ Graphical Web 2014

September 8th, 2014

Just recently I had the chance to talk about authoring animations of CSS/SVG for better performance at The Graphical Web 2014. I thought I’d put up the slides here in case they’re useful to others.

In the rare chance that you’re reading this blog directly or the syndicator didn’t eat this bit, you can view the slides right here:

Web Animations @ html5j 2013

December 4th, 2013

Over the weekend I had the chance to speak about Web Animations at the HTML5 conference 2013 in Tokyo. I put a fair bit of work into the presentation so I thought I’d put up an English version of the slides (including videos of the demos) in case they’re useful to someone else looking for a gentle introduction to Web Animations.

I ran out of steam when producing the last few slides so it kind of ends with a fizzle but I put a fair bit of work into the other ones so hopefully it’s entertaining. Although you can’t tell from the slideshare version most of the slides include animation somewhere and most of the pictures are made with SVG so I think it looked pretty.

View the presentation slides

In the rare chance that you’re reading this blog directly or the syndicator didn’t eat this bit, you can view the slides right here:

(If you’re curious there’s the HTML version too. But be warned that it doesn’t have explanatory notes like the slideshare version; it won’t work in Chrome since it makes heavy use of scoped styles; and one animation relies on enabling mixed-blend-mode which is only in Aurora or Nightly, see bug 902525.)

(日本語の資料ももちろんあります!イベントの配信、 分かりやすくしたスライド, 原本のHTML版のスライドをご覧ください。)

Players wanted: the pause and seek game

July 25th, 2013

Last time I introduced timing groups in Web Animations as a simple yet powerful tool for synchronising animations. Great as they are, the open up a few interesting questions. For example, what happens when you pause an animation that’s in a timing group?

Consider the following parallel timing group. It has two child animations, A and B, and the group repeats twice.

A parallel timing group with two children A and B whereby the group repeats twice

Suppose we pause child animation A at the red down arrow and then resume it at the red up arrow. What should happen?

One option is to just let everything play as normal.

A child of the parallel timing group is paused such that all other animations continue to play as normal

But then what happens to the second run of A? Does it run at all? Get squashed? Get overlapped? And if so, who wins?

So what if we automatically unpause animation A when we hit an iteration boundary?

A child of the parallel timing group is paused such that it is automatically unpaused when an interval boundary is reached

From an API point-of-view that automatic unpausing is tricky and likely to lead to bugs where a piece of script assumes an animation is paused but on some devices the interval boundary occurs before the script gets a chance to run, breaking the assumption.

Another approach is just to stretch the iteration to fit the pause like so.

A child of the parallel timing group is paused such that the iteration is stretched to fill the pause amount

This mostly works for parallel containers but, like the other behaviours, it doesn’t make sense for a sequence timing group because the sequence is broken.

Also, all these behaviours are problematic if we seek the group whilst a child is paused. And if we seek backwards after unpausing what is the expected state of the world?

The approach that provides the most intuitive behaviour in these situations is simply to pause the group as a whole like so.

A child of the parallel timing group is paused by applying the pause to the group

This of course applies all the way up the tree.

But what do other APIs do?

Looking at a number of other animation APIs:

  • QML just ignores play control on animations if they’re in a group.
  • Android doesn’t include repeating etc. on groups and animations and groups don’t have play control.
  • In WPF only the root clock can be interactively controlled.
  • In HTML, media slaved to a controller (similar in some sense to a timing group) behaves differently to independent media. You can pause it independently, but seeking throws an exception. Pausing due to buffering pauses the controller. There is no repeating.

In summary, QML and WPF push pausing to the root of timing hierarchy. Android and HTML manage to do something different but only because they don’t allow groups to repeat.

For Web Animations, like QML and WPF, the best option is to push pausing and other play control to the root of the timing hierarchy. The trouble comes when we try to represent this in the API.

At first we tried to do this transparently, that is, you’d call pause and it would just go up to the top-level timing group and apply the pause there. However, a couple of concerns were raised with this,

  • It’s not obvious that the operation you’re performing may have wide-reaching effects.
  • It doesn’t work for seeking since the time values are relative to the child not the parent. HTML just throws an exception in this case, but some people felt uncomfortable that this method would sometimes work and sometimes throw an exception depending on whether there was a parent timing group or not.

Enter the players

In order to emphasise the fact that play control (pausing, seeking, etc.) takes place at the root-most timing group a new concept, the player, was introduced. A player plays things. It’s the point of attachment between some timed content and a timeline. The arrangement is as follows.

Players form the point of attachment between the rootmost timing groups and animations and a timeline.

From a code point of view it looks like this:

  var anim = elem.animate({ left: '20px' }, 3);
  anim.player.pause();

This separation hopefully makes it more obvious to an author that the change they are making may have more wide-reaching effects.

It also can make avoiding some common coding mistakes a little easier.

  // The following could cause some animations to be sped up 4, 8 times or more
  elem.getCurrentAnimations().forEach(function (anim) {
    anim.player.playbackRate *= 2;
  });
  
  // The following will speed everything up by a factor of 2 and no more
  elem.getCurrentPlayers().forEach(function (player) {
    player.playbackRate *= 2;
  });

It also has a few nice properties:

  • TimedItem.localTime is always readonly and has a different name to the always writeable Player.currentTime.
  • TimedItem.timing.playbackRate affects the model in the same way as changing other timing parameters does including possibly causing the playback position to jump. Player.playbackRate, on the other hand, makes dynamic changes so that the current playback position is preserved.

Unfortunately, introducing the idea of players adds conceptual weight to the API. It’s probably one of the most unfamiliar concepts for people coming to the specification (hence this blog post!). For these reasons I resisted this change strongly but ultimately lost. :)

That said, it does make the model more consistent and therefore, to some degree, more intuitive. It is also expected that many authors will never use this functionality (jQuery, for example, does not provide pause control) and so this additional concept shouldn’t become a barrier to adoption for simple usage.

I’ll look forward to seeing how authors take to this concept. If you have any feedback, feel free to follow-up at public-fx@w3.org with subject [web-animations].

Upcoming changes

Recently we’ve been discussing some changes to the way players work. Currently they just keep playing forever but we think it might make sense for them to behave more like a VCR and stop when they hit the end of their media. This would allow us to define a reverse() method that behaves sensibly and perhaps make players then-able.

You can see some of the discussion in the minutes from our recent telcon, item 6, Making players stop. As always, your comments are welcome at public-fx@w3.org.

Group and conquer: timing groups for your synchronization woes

July 9th, 2013

Once you start animating anything more than simple fade and slide effects, pretty soon you start wanting to synchronize things. The penguins should start dancing together, the watermelon should explode the moment the blind-folded person hits it, the credits should roll after the movie finishes and so on.

In this post I want to outline the approach taken to these problems in Web Animations and the biggest new feature in the spec: timing groups. But first, what can we already do?

Synchronization in CSS

In CSS you can do a few things:

  • By toggling a style on a common ancestor you can get two animations to start at the same time. For example, see this example from Smashing Magazine.
  • Using animation-delay you can stagger the start times of animations and by calculating the length of A, you can use this to make B start after A.

There are a few limitations though:

  • It’s not particularly scalable—if A changes duration, you need to update B as well. That’s particularly problematic if, for example, A is a video of unknown length.
  • You’re not declaring the temporal relationships between different animations—their synchronization is just a by-product of how you triggered them—and as a result there’s no easy way to pause or seek a particular set of animations.
  • It requires you to structure your document so that you’ve got a common ancestor to toggle a class on. Suddenly your document structure is doing triple duty: semantics, layout (all those empty <div>s to persuade CSS to do what you want), and timing.
  • You can’t create animations on the fly that line up with already running animations.

The problem with SVG and syncbase timing

SVG has a neat feature which seems to meet these needs: syncbase timing. That lets you create arrangements like:

<animate id="a" begin="b.end" ... />
<animate id="b" begin="0s" end="c.end" ... />
<animate id="c" begin="a.begin+2s" ... />

That would seem to do everything we could ever want, except it has a few problems:

  • It’s complex. The above example is just the tip of the iceberg. You can have any number of conditions on both the begin and end of an animation pointing to any other animation including the same animation. You can create cyclic dependencies and some are allowed, some are not, and the rules for breaking cycles are vague (and thus, inconsistently implemented).

    What’s more, all this feeds in to the most complex part of SVG animation: deciding what intervals to create. As a result if you want to determine what animations are active at a given time, you have to step through all the significant moments up to that time and work out what intervals to create. This makes seeking costly.

  • Another problem is that you can’t cancel just part of such a sequence.

    For example, imagine you have a sequence of actions A, B, and C representing “fade the background of the button from grey to blue”, “pulse it”, then “make it glow”. You trigger A when the mouse moves over the button but the mouse suddenly leaves while A is still running. You cancel A (e.g. using end="mouseout" or endElement) but then B still runs since it sees that A has ended. And consequently C also runs. There’s no way to cancel the chain and nor is there any way to seek/pause such a chain independently of other animations that might be running.

Enter timing groups

These use cases can be addressed using the concept of timing groups. This is a well-established concept in animation APIs. For example,

  • QML has ParallelAnimations and SequenceAnimations.
  • SMIL has <par>, <seq>, and <excl> time containers.
  • Android has AnimatorSets that play animations together or in sequence.

Common to all these APIs is the concept of two types of groups: groups that run animations together and groups that run animations in sequence.

Furthermore, in each of these APIs the two types of groups can be nested so you can easily build complex arrangements up from simple parts in a way that is easy to reason about.

For example, the following arrangement:

<animate id="curtainOpens" ... />
<animate id="penguinADances" begin="curtainOpens.end" ... />
<animate id="penguinBDances" begin="curtainOpens.end" ... />
<animate id="curtainCloses" begin="penguinBDances.end" ... />

could be represented with timing groups as:

<seq>
  <animate id="curtainOpens" ... />
  <par>
    <animate id="penguinADances" ... />
    <animate id="penguinBDances" ... />
  </par>
  <animate id="curtainCloses" ... />
</seq>

Graphically, the arrangement is as follows:

A sequence timing group that contains a parallel timing group as a child. The parallel timing group waits for the previous child of the sequence timing group to finish, and then the children of the parallel timing group play simultaneously. After they have finished the next child of the sequence timing group plays.

You can cancel a chain of animations in this case by simply cancelling the group. The hierarchical nature of the groups also means seeking is constant-time with regards to the seek interval.

Timing groups in Web Animations

In Web Animations we have adopted this same approach of using timing groups with the following features:

  • Two types of timing groups: parallel, sequence.
  • Children of a group can have a delay which can also be negative. This allows children of a sequence group to overlap so you can, for example, start a fade animation 2s before a video ends. (SMIL does not allow negative delays on children of a sequence group.)
  • Any timing property you can apply to an animation, you can also apply to a group which means you can repeat, ease, reverse, delay, or speed up a group.

The last point is interesting since most other APIs don’t do that. It can be quite useful as we showed in a demo of this in our preview video last October where we combined a door closing animation and a creaking sound “animation” in a group then eased the group.

However, it introduces some complexity. For example, since easing functions can be non-invertible, it means you can’t always convert from child time to group time which complicates event handling.

Also, the interaction between fill modes specified on a group and on a child are not always obvious and we need to revise the spec to be more intuitive in this area.

Building up the example above using the API in Web Animations look like the following.

document.timeline.play(
  new SeqGroup([
    new Animation(...),   // Curtains open
    new ParGroup([
      new Animation(...), // Penguin A
      new Animation(...)  // Penguin B
    ]),
    new Animation(...)    // Curtains close
  ])
);

On a side-note, we’ve had some feedback about ParGroup and SeqGroup being a bit cryptic, especially for anyone not familiar with SMIL (which is pretty much everyone). ParallelGroup would be more readable but it’s a lot to type for something we expect authors to use a lot. I wonder if just Parallel would make sense? Perhaps this could be a named constructor for ParallelGroup? If you have any suggestions we’d love to hear them. Either respond here, or, better yet, send a mail to public-fx@w3.org with subject [web-animations].

The mapping of timing groups to SVG and CSS has yet to be worked out.

Future extensions to timing groups

One common request that arises in regards to timing groups is the ability to set the duration of the group and specify the duration of the children as fractions of that parent. That sort of adaptive duration is something that’s quite useful but also can easily become complex—like CSS flexbox in the temporal domain. It’s something we’ll look at in a future version but for now we’re comfortable it can be added to the model and API fairly naturally.

If you want to read up on the detail, have a look at the spec. As always, your comments are welcome at public-fx@w3.org with subject [web-animations].

Introducing Web Animations

June 26th, 2013

Today we finally shipped the First Public Working Draft of Web Animations!

Over the coming weeks I’d like to introduce some of the key concepts as well as some of the issues that need your input.

First, I’d like to give an overview of where the spec comes from and what it covers.

Why Web Animations? A summary of happenings until now

On the Web today we have CSS Animation (including Transitions) and SVG Animation and they both have their problems. For example, CSS is so simple it doesn’t even support synchronization and SVG is pretty hairy when it comes to interval negotiation and syncbase timing—and it’s SVG-only. Most of all though, they’re completely separate.

Also, Microsoft don’t support SVG Animation. They have consistently maintained that they want to see a single model for animation on the Web (e.g. minutes) and that that model should have an API. That’s a very reasonable position in my mind, albeit frustrating for authors who want to use SVG Animation now.

The story since then is as follows:

What’s in the box?

Basically, this:

Intersection of features provided by CSS, SVG, and Web Animations

Web Animations is essentially a common model for animation that underlies CSS and SVG. It covers the common features of both plus a few only found in one or the other.

It also has a few extra features not currently found in either:

Timing groups
This is the primary means of synchronization.
It’s quite powerful but I’ll leave the details and justification for this to a separate post.
Speed control (#1 and #2)
This is a requested feature for SVG2 and may be useful for achieving reversing effects such as exposed in CSS.
Custom effects (API)
This allows the Web Animations timing model to be used to drive animations of HTML canvas etc. by registering a script callback.
Iteration start
This is a minor but much requested feature that allows you to start an animation part-way through its interval.

What’s not included?

Bear in mind that Web Animations is essentially a model. It’s not a declarative syntax. That’s something left to other specs. The API happens to be bundled with the model simply because that makes it easy to keep the two in sync.

The arrangement is as follows:

Intersection of features provided by CSS, SVG, and Web Animations

The CSS-specific features required for CSS animations and transitions will be covered in a separate specification, possibly called “CSS Animations/Transitions level 4” which expresses its features in terms of the Web Animations model.

Likewise, current SVG features such as syncbase timing, or targetting attributes (not just CSS properties) will be covered by a separate specification (my next task) expressed in terms of that model. That specification may be called something like “SVG Animation” but I suspect not since quite a few people have expressed interest in allowing it to apply to HTML content too.

Other features that are not included:

  • Bounce/spring timing functions – we really wanted to make this possible and have a couple of simple extensions to timing functions to allow this but we haven’t yet reached agreement about which one is best so we’re leaving them both out for now.
    The plan is to follow up with a separate specification which provides additional timing functions anyway.
    (In fact, with the current working draft, you can’t even do more than one timing function over an animation currently but that will be fixed in the next draft when we introduce chained timing functions).

  • Media integration – this is something a lot of people have been asking for but we decided to postpone it in the interests of progressing the spec along.
    The good news is this used to be part of the spec so we know it integrates very cleanly.
    For now we’ll work on it in a separate spec and if that comes along quickly enough we might merge it back in.

  • State machines – this is something that is very useful when you start programming UI interactions but something we decided is not critical for the first version of the spec.
    Again, we’ll probably work on this as a separate spec.

API?

Originally I opposed the idea of adding an API because I think declarative solutions are generally preferable. However, the API is useful in a few cases:

  • It lets you inspect the state of all animations in the document. Anyone can build developer tools that present you with a timeline of all the running CSS animations/transitions/SVG animations in the document for debugging.
  • It lets you make runtime changes to declarative animations—for many apps a combination of declarative and procedural approaches is the best fit and lets you achieve effects that might not be possible using purely declarative features.
  • For some problems a procedural approach is suitable and in those cases using the API is both simpler than writing the animation loop yourself and also means the browser can optimise the animation for smoother performance and less battery consumption.

Implementations?

Work has started on implementation in Blink and is on the radar for Gecko. Until then a polyfill is coming along in leaps and bounds and covers nearly all of the FPWD.

That’s it for now. I’ll follow up with posts explaining specific features and issues needing input but if you have any feedback on the spec, don’t hesitate to send it along to public-fx@w3.org with subject [web-animations]. Thanks!

Help with math(s)

January 15th, 2013

UPDATE: I originally prepared this post before others working on the Web Animations spec assured me they would find a solution. I posted it password-protected for their sake not realising it would show up on planet! Sorry! Anyway, here is the original post for those who were curious. There are already some folks working on this, but other input may still be useful!

One of the limitations of CSS and SVG animations is that you can’t do a bouncing effect. That is, you can’t easily do this:

Bouncing in SVG. Click the circle to restart.
(If the image fails to show, try this link: http://people.mozilla.org/~bbirtles/blog/bouncing.svg.)

You can emulate it (as above), but it really should be the job of the timing function to do this kind of easing.

In Web Animations we’ve been trying to address this. At first I tried creating a simple smoothing function where you’d specify a series of points and it interpolates smoothly between then. This proved more complex than expected so I narrowed the problem down to just spring-like animations.

It’s easy to generate a spring-like function—I found a sine wave plus exponential dampening plus some scaling of the period does ok, but in terms of parameterisation I think you probably want the following handles:

overshoot
How far past the target value to reach on the first cycle of the spring-like motion. 1.5 means overshoot by 50% (when exposed to CSS and SVG, this parameter might be exposed as just ‘50%’ instead of 1.5). This is particularly useful if, for example, you’re animating something inside a container and want to be sure the effect won’t fall outside the bounds of the container.
elasticity
How much should it bounce back and forwards before converging on the target value? Higher numbers mean more bouncing. After discussing with the others working on Web Animations spec, this may or may not be the most suitable parameter. If at all possible however we want to reduce the number of parameters to avoid being as complex as QML.

Parameterising the spring function in those terms proved a bit beyond my mathematical abilities. I made the following prototype but it’s all kinds of clumsy.

If the iframe above doesn’t appear, try this link: http://jsfiddle.net/CZ3Kn/11/embedded/result/.
Note that it won’t work in Internet Explorer since IE doesn’t support SVG animation.

Problems:

  • Doesn’t work in all ranges. For example, for an overshoot of 5, the second peak is higher than the first. An overshoot of 1 also doesn’t work.
  • The first part of the curve (on the initial path to the overshoot value) seems wrong—sometimes there are lumps or kinks in it.

Rough requirements for the function, f(x):

  • overshoot is a value in the range [1,∞)
  • elasticity — not even sure if this is the right parameter. It would probably be ideal if elasticity of 1 simply made the animation go to the overshoot value and then return to 1 without any bouncing. A value of 2 might make it overshoot once, dip below 1, then return on 1.
  • For 0 ≤ x ≤ 1 the global(?) maximum of the function is overshoot and this should also be the first maximum in the range
  • f(0) = 0 and f(1) = 1
  • When elasticity is high or overshoot is high it should probably reach the overshoot value sooner since the bounce component will take longer to complete
  • The function should probably not go negative initially, unless overshoot > 2 in which case it might be ok.
  • Not sure if the first part should be ease-in.

As I said, there are already some folks working on this, but if you want to have a try you can fork the fiddle above and hack away. Alternatively, there is an Excel spreadsheet or OpenDocument spreadsheet version.

On the other hand, if you think this is not the most useful function or something more general is possible, feel free to suggest that too!

Web Animations

October 31st, 2012

It must be time for my biannual blog post and this time I’d like to introduce a new development in animation for the Web, called, creatively enough, Web Animations.

Some of you may have heard rumblings of an attempt to overcome some of the limitations with both CSS and SVG animations and unify them at the same time. Well, that’s what some folks at Google, Adobe and myself (Mozilla) are trying to do.

I’ve put together a video of some of the ideas we have so far:



An in case the video gets synderadicated here’s a Youtube link: https://www.youtube.com/watch?v=VvNQNtIfXXI

If you’re interested in the details, the latest version of the spec is here:

https://dvcs.w3.org/hg/FXTF/raw-file/tip/web-anim/index.html

A few points to bear in mind:

  • There are still lots of holes. The behaviour of pausing and reversing is particularly in flux at the moment and the integration with media is still just thoughts, yet to be fleshed out and spec-ified.
  • The integration with CSS and SVG will be specified in separate documents (just placeholder text for now).
  • If you’ve got suggestions, please feel free to send feedback to the public-fx W3C mailing list with the subject [web-anim] at the start of the subject.
  • Progress from my end has slowed down recently due to some workshops I’ve been involved in but I’ll hopefully be back into it by the end of November.
  • We have a shim in the works (that’s what the video uses) but it’s currently awaiting approval for release. Should be ready soon.

Parapara Animation

January 27th, 2012

About a week ago Mozilla Japan put on a two-day event in Tokyo called Mozilla Vision 2012. It was a great weekend with several hundred people coming to talk about what it means to be Open, and, in very Japanese-style, see some cool robots (courtesy of Takahashi Tomotaka-san).

Personally, I was involved in running the Parapara Animation Workshop* where kids enjoyed drawing simple frame-based animation on a tablet which was then added to a much bigger animation projected on the walls. The purpose of the project was to teach kids the basics of animation as well as to encourage them to be not just web spectators but web makers.

It’s a workshop that was originally done by a group of Keio University Students and they helped run it again this time. The main difference is that last time it was mostly iOS-based, this time it was all Web.

Christian Heilmann has written up a great summary of this part of the program including a quick interview where you can see how it worked.

Japanese kids are really creative so it was a really fun time. But not only was the event fun, the technology side was really fun too.

Some of the technology used

What went well

  • SVG’s native motion on a path (<animateMotion>) saved us so much time. The auto-rotate feature (rotate="auto"), path APIs (getPointAtLength), and ability to calibrate the path length (pathLength="1") also made it easy to position animations at just the right place so they would appear on the screen as soon as the user pressed “send”.
  • Using SVG made it really easy to do the drop shadows. Just a transform and a blur filter and we were done.

  • SVG animation was surprisingly fast. I expected it to be really slow but it was the fastest of the alternatives we tried. That said there’s still a lot more work to be done (see below).
  • Overall SVG just proved really versatile. Being able to show a faint greyed outline of previous frames just by setting an attribute was great. Likewise being able to do all the animation work on the client-side and then just serialise the subtree and send it to the server was so much simpler than the previous version.
  • Deployment over the Web was great. Just refresh the page to pick up the bug fixes! Likewise when we ran out of tablets at one point we could just load up the editor URL on a laptop and keep drawing.

What didn’t go so well

  • The app marketplace. We badly wanted to package it all up as a Web app using the framework developed by the Mozilla Labs Apps project. We hoped that would give us full-screen display and stop the user from accidentally navigating to other pages. We had high hopes but were shattered to find the Android runtime launched the app in a Webkit runtime which didn’t even support SVG.
  • Going full-screen. Due to some technical reasons we were stuck with an old version of Fennec and old UI which took some coaxing to go full-screen and stop the chrome from flying in when the user was drawing. Fortunately the bugs that stopped us from using a more recent version of Fennec appear to have been fixed so next time we can hopefully use the Fullscreen API and multi-touch for drawing with all your fingers at once (something the really young kids really wanted to do!)
  • CSS and UI layout. Countless hours were sunk into trying to convince CSS to layout widgets on the screen. In the end I gave up and did half of it in script. I’m told CSS flexbox can help a lot here but I spoke to one implementer of flexbox who said that some of the things we were trying to do weren’t possible even with flexbox.
  • Graphics performance. For the combined animation we badly need a boost to our SVG rendering performance. On Windows the performance was generally ok (if you don’t have a loud fan!) but occasionally got jittery. On Mac it looked terrible. We still have a way to go here. Apart from the graphics performance there’s still lots of room to optimize SVG animation itself too. For the editor running on the tablets, I have one patch awaiting review which I hope will make using SVG’s path APIs faster and speed up the drawing and erasing operations.

The result

The gallery of animations:

http://parapara.mozlabs.jp/MozillaVision2012/

The editor:

http://parapara.mozlabs.jp/MozillaVision2012/editor/

And, of course, the code is waiting for your help at github!

Feedback

“That’s a web page?!?” I’m certain that most people who used the demo were oblivious to the fact they were using the Web and that’s probably the greatest success of this demo. Without exception, everyone who asked about the technology was surprised it was Web-based. Everyone assumed it was a native Android app or otherwise Flash.

“That’s SVG?!?” The web developers who came were also surprised at the use of SVG. Most had never really thought of making use of it. They assumed we were using canvas.

“I want to cry, this is the first time I’ve seen Fennec used for something other than reading the news”

Although a lot of the features we used are still in development it was very rewarding to see how much is already possible with Open Web technologies. We’ve had many requests to run this workshop elsewhere and, with your help, it will hopefully get better each time. Thanks very much to the Parapara Animation team and to everyone who contributed to Fennec, Gecko and the Web standards that this is built on.

* For anyone wondering what “parapara” means, it’s the sound of flipping paper and its use here comes from “parapara manga” which means “flipbook comic”. It’s also the name of a kind of hand dancing so we might have to reconsider the name so as not to disappoint the kids.

It’s about time…

October 13th, 2010

Firefox 4 is going four dimensional! Time dimensional! (Ok, for those who know physics, just pretend :)

There’s CSS transitions for all sorts of animated eye-candy, major JS speed-ups to give scripted animations a boost and mozRequestAnimationFrame to get keep them smooth and in sync, and a whole host of other graphics and video improvements. Oh, and SMIL in SVG!

Speaking of which, I thought I’d bring you up to speed on some of the recent progress on the SMIL front.

Event timing

One of the more recent additions to our implementation is the ability to key animations off DOM events such as mouse clicks and key presses.

This paves the way to creating widgets of questionable aesthetic value:

That button
(View demo. You’ll need to be running a recent nightly to experience this button is all its tacky glory. With the latest Firefox 4 beta the motion will be jerky due to bug 557885.)

However, SMIL animations need not only be keyed off SVG events but any event in the current document is fair game. So, for example, suppose we want to add a tape animation that runs whenever a certain video is in play, we can do it with this piece of SMIL:

<animate attributeName="stroke-dashoffset" from="0" to="90"
dur="1s" repeatCount="indefinite" fill="freeze"
begin="video.playing" end="video.pause; video.ended"/>

Demo of video with SMIL-animated icon synchronised with the video playback state
(View demo)

In addition to events, you can also key animations off:

  • key presses: <animate begin="accessKey(a)+1s"…
  • other animations: <animate begin="otherAnimation.begin-2.5s"… (and this is generally a much better choice than event timing when you want to keep animations in sync. Although you can write begin="otherAnimation.beginEvent" you may get surprising results when a seek is performed. Use begin="otherAnimation.begin" instead.)
  • repeat iterations: <animate begin="otherAnimation.repeat(2)+25ms"…
  • plain old time offsets: <animate begin="12.3h"…
  • all of the above! <animate begin="rect.click; accessKey(a)+1s; otherAnimation.begin-2.5s; otherAnimation.repeat(2)+25ms; 12.3s"…

SMIL and script are friends

There are a lot of advantages to using SMIL over script (it’s generally easier for a start!) but sometimes it can’t do everything you need. In those cases you can use both together!

SMIL → Script: To synchronise script with SMIL, just listen for the relevant time events generated when animations start (beginEvent), repeat (repeatEvent), and stop (endEvent). If you need a bit more context you can always query the animation’s start time and current time too.

Script → SMIL: To go the other direction, that is, to kick-start SMIL from script, just use the appropriate time control interfaces beginElement, endElement on the target animation, or seek and pause all animations in the <svg> block as a whole with setCurrentTime, pauseAnimations and friends.

SMIL outside the box

While we’re only supporting SMIL for SVG content that doesn’t mean it’s entirely off limits to your HTML content. Not only can we tie SMIL to HTML events as above but we can also apply various SVG features to HTML, and these places can play host to a bit of declarative animation too.

Woah woah woah! Example of a SMIL-animated SVG filter applied to HTML content.
(View demo)

What’s left?

Still, there are a few features missing in our SMIL implementation that are yet to come. I’m maintaining a somewhat detailed summary, but in short we’re missing:

  • Mexican waves — There are still a few SVG data types that can’t be animated yet. Paths are very much on the way, but lists of points are yet to come. That means all your squiggling, warping, barrelling, twisting, waving lines and stars will have to wait a little longer to mesmerise the world. Hopefully most of this will be done in time for Firefox 4.
  • Hyperlinking — The ability to trigger animations from a hyperlink is also yet to come but will probably not make it’s debut until after Firefox 4.0.

What’s not on the radar?

There are also a couple of features that are neither done, nor likely to get done in the foreseeable future. These are:

  • <animateColor> — So long as <animate> honours color-interpolation then <animateColor> isn’t necessary and only complicates the Web. See bug 436296. We recommend using <animate> instead. (This issue was recently discussed on www-svg.)
  • Wallclock timing — That is, the ability to set up an animation to begin at 2011-01-01T00:00:00+09:00. Real uses cases for wallclock timing were discussed on www-smil earlier in the year but it seems the syntax provided by SMIL, at least as far as it is used in SVG, is insufficient for these use cases. For the time being, we’d rather not clutter the Web platform by implementing something half-baked. For most use cases, it should be possible to provide this sort of functionality by adding a sprinkling of script to your SMIL.

UPDATE: I just noticed Robert Longson (who’s played a big part in us getting to this point) beat me to reporting much of this news, so for more details on where we’re up to see his post too.


css.php