Dart Widgets Dev Journal 1 - Basic Animations
tl;dr: Implementing features similar to Bootstrap is hard without basic animation support in Dart. Basic animation support is not as easy as you'd think. I've made a stab. Check out the demo.I've started a new Dart project - Dart Widgets. The inspiration is Bootstrap, but with a focus on features that map cleanly to Web Components.
While digging into Bootstrap, I realized that there was a heavy dependency on jQuery--specifically the show/hide/toggle functionality. This is critical for expanders, menus, modals, pretty much everything.
Show, hide, toggle
It turns out implementing show/hide/toggle is not as easy as one might guess.One could naively toggle
display: none;
in an element's style attribute and call it a day, but a lot of edge cases would be missed.Throw in the ability to optionally animate the show/hide behavior and things get a lot more complicated.
A short list of the cases to ponder:
- Element with a non-standard display value. (e.g. a div inherited a display of inline-block)
- Element with a local display of none
- Element inherited a display of none
- Show is called while an element is hiding and vice versa
- Toggle is called 10 times before the first animation finishes
- Show is called on an element with effect A while effect B is hiding it.
Test
I can't tell you how valuable test-driven development was in getting this project off the ground. It would have been next to impossible to ensure all of the edge cases were handled cleanly.I need to write another post about how my approach to testing in Dart has evolved. Let's just say I didn't code up 939 tests by hand.
After a lot of head scratching, I think I ended up with pretty clean, extensible model.
As proof, I offer the code for doing a open/close door effect:
class DoorEffect extends Css3TransitionEffect {
DoorEffect() : super(
'-webkit-transform',
'perspective(1000px) rotateY(90deg)',
'perspective(1000px) rotateY(0deg)',
{'-webkit-transform-origin': '0% 50%'}
);
}
There are still a few things I'd like to get working--get tests working in Firefox, find a way to handle browser prefixes cleanly--but generally I'm happy with progress.
Check out the demo.
Check out the code.
Let me know what you think.