Wednesday, December 9, 2009

SVG/SMIL "Dock" Demo

Today, I decided to see what what it'd be like to make an MacOS-style "dock" in SVG, using SMIL <animateTransform> elements to achieve the zooming hover effects.

Once I got that working, I felt like I really should make the icons do something useful when you click them. So, I hooked them up to control an embedded iframe.

Here's the result: SMIL Dock



(Note that the demo will only do anything useful in a mozilla-central nightly build -- that is, Firefox 3.7 / Gecko 1.9.3 -- since earlier versions don't have support for SMIL.)


Robert said...

A couple of additional Dock behaviours that might be hard to implement with SVG/SMIL:
-- if you move the mouse away from an icon while it's growing, it should stop growing and shrink back to the normal size
-- the icons should be packed horizontally, so enlarging one icon pushes the others aside

Marek said...

Nice demo! ;-)
I think there's i typo mistake in the text, double what, but maybe I'm wrong...

Anonymous said...

Works with Opera 10 too.

voracity said...

Aren't you worried that Apple will now sue you? (Sorry, bad joke.)

@Robert: Why would those be difficult in SVG/SMIL? I haven't done much SVG, but I can think of some (perhaps naive) ways of doing it in HTML using basic mouse outs for the first and inline-block (+ positioning) for the second.

Alfred said...

Even nicer if you make the html frame the whole view, so that the dock is above the frame itself.

Jeff Schiller said...

Nice Daniel! But surely you can get it working in Chrome/Safari? :)

Daniel said...

@Robert: The first thing you mentioned (interrupt & shrink on mouseout) already works, though perhaps I made the growing-animation too quick for it to be detectable. Here's a slowed down version where that's more noticeable.

As for the second thing you mentioned -- I think a simple version of packing should be achievable by adding 2 additional animations to each element: "shift left" and "shift right". And then whenever we play the zoomin/zoomout animation for dockitem N, we play the corresponding "shift" animation for all the items to its left & right.

(I'm realizing that syncbase timing will indeed make a lot of this stuff easier. :))

@Marek: Thanks!

@Anonymous: Good to know that it works for you in Opera. On my Ubuntu system, it appears to hit some pathological case in Opera 10.10 -- it goes very slowly, and it prints out tons of messages saying "X11OpBitmap::GetPainter(): Painter exists". I'll try to see what's causing that out at some point, if I get a chance.

@voracity: see above response to Robert. I am indeed using a mouseout handler to handle the first.

@Alfred: Agreed, that would be cooler -- I actually did try having the dock over the iframe, but that currently causes some minor repaint issues :) When the icons shrink, we sometimes leave empty blocks unpainted (for less than a second) in the iframe behind them. This happens a lot when the page in the iframe is loading, i.e. when you've just clicked an icon. That bothered me, which is why I moved it lower for now.

@Jeff: Thanks! :) I'll try to get it working better in WebKit in the next version of the demo.

Brian said...

I think what Robert might have in mind though is that it should shrink back at the same rate it grew. Currently I think even if you get a mouse out after 0.1s it will still take the full 0.2s to shrink back. I haven't run the demo however so I could be wrong.

Daniel said...

@Brian: Ah, good point -- the zoom-out operation will indeed get a full duration, regardless of when we interrupt the zoom-in operation.

I suppose I could get around that by storing the result of "getCurrentTime()" when the zoom-in operation begins & when it's interrupted. Then I could dynamically set the zoom-out operation's duration to be the difference between those two values. :) Seems a bit hacky, but I can't think of a more elegant way to accomplish it at the moment...

Brian said...

Yeah it's possible with script but I haven't thought of a way to achieve it with SMIL alone.