Animations in HaxeUI2

Animations in version 1 of HaxeUI were a little bolted on as an afterthought, and therefore didn’t really work too well and weren’t really customizable. You could set a “type” of animation (slide, none, fade for example), but then it was up to the component whether it took any notice of it. More over if you wanted to change the animation you would have had to subclass the component or edit the code directly – all in all not a good sub system!

I’m not a massive fan of UI animations, I think they commonly get overused and have a detrimental effect on performance and the “professional feel” of a serious application. That said, I do think they have their uses, especially for applications that are supposed to be a little “funky” and not all about the raw data the app is presenting. Also, when done right I think they can increase the user engagement and generally leave a good taste in the users mouth about the app (we’ve all used some pointless app before but been sort of impressed by how the UX felt rather than what it actually did I’m sure).

The new animation sub system in HaxeUI2 is pretty flexible, first of all, here’s some mark-up:

<animation>
    <keyframe time="0">
        <button1 left="0" top="0" />
        <button2 left="100" top="0" />
        <button3 left="100" top="100" />
        <button4 left="0" top="100" />
    </keyframe>
    <keyframe time="500">
        <button1 left="100" top="0" />
        <button2 left="100" top="100" />
        <button3 left="0" top="100" />
        <button4 left="0" top="0" />
    </keyframe>
    <keyframe time="1000">
        <button1 left="100" top="100" />
        <button2 left="0" top="100" />
        <button3 left="0" top="0" />
        <button4 left="100" top="0" />
    </keyframe>
    <keyframe time="1500">
        <button1 left="0" top="100" />
        <button2 left="0" top="0" />
        <button3 left="100" top="0" />
        <button4 left="100" top="100" />
    </keyframe>
    <keyframe time="2000">
        <button1 left="0" top="0" />
        <button2 left="100" top="0" />
        <button3 left="100" top="100" />
        <button4 left="0" top="100" />
    </keyframe>
</animation>

As usual the mark up is just a shortcut for a macro that builds the code for you, you could certainly create all the key frames, properties, component refs, etc yourself in code. It’s not hard at all, but the mark-up is more re-useable. I toyed with implementing a CSS type animation framework, but I’ve always found it pretty unintuitive. I think the “key frame” approach is pretty simple. To run that previous animation, you simply need:

    animation.setComponent("button1", _button1);
    animation.setComponent("button2", _button2);
    animation.setComponent("button3", _button3);
    animation.setComponent("button4", _button4);
    animation.loop();

The result is this.

So that’s all fine, but I also wanted to be able to use this same sub system in the components themselves, so the module.xml can now define animations for components, an example of this from haxeui-core module.xml is:

	<properties>
		<property name="haxe.ui.components.hslider.animation.pos"
                    value="haxe.ui.components.animation.pos" />
		<property name="haxe.ui.components.hslider.animation.rangeStart"
                    value="haxe.ui.components.animation.rangeStart" />
		<property name="haxe.ui.components.hslider.animation.rangeEnd"
                    value="haxe.ui.components.animation.rangeEnd" />

		<property name="haxe.ui.components.vslider.animation.pos"
                    value="haxe.ui.components.animation.pos" />
		<property name="haxe.ui.components.vslider.animation.rangeStart"
                    value="haxe.ui.components.animation.rangeStart" />
		<property name="haxe.ui.components.vslider.animation.rangeEnd"
                    value="haxe.ui.components.animation.rangeEnd" />
		
		<property name="haxe.ui.components.hscroll.animation.pos"
                    value="haxe.ui.components.animation.pos" />
		
		<property name="haxe.ui.components.vscroll.animation.pos"
                    value="haxe.ui.components.animation.pos" />
	</properties>
	
	<animations>
		<animation id="haxe.ui.components.animation.pos" ease="Bounce.easeOut">
			<keyframe time="300">
				<target pos="{pos}" />
			</keyframe>
		</animation>
		<animation id="haxe.ui.components.animation.rangeStart" ease="Bounce.easeOut">
			<keyframe time="300">
				<target rangeStart="{rangeStart}" />
			</keyframe>
		</animation>
		<animation id="haxe.ui.components.animation.rangeEnd" ease="Bounce.easeOut">
			<keyframe time="300">
				<target rangeEnd="{rangeEnd}" />
			</keyframe>
		</animation>
	</animations>

Putting this in the module.xml means that other modules (ie, an app, a lib, etc) can easily override them to achieve different effects, by either creating a new animation with the same id, or by overwriting the property of a specific component class. It also means you have a central place to store animations should you wish to use it – you, of course, don’t need to – you could load them from somewhere else or create them in code. You can also override each component instances’ animation with a simple call to Component::setClassProperty(…) should you wish a non-standard animation for a single component.

You can see the component animations in action here by clicking on the background of the hslider in order to make it jump to a value, previously (without animations) it would simply set the value directly. The components on that page are also bound to each other, so changing one value results in changing most of them, this is also honoured with animations of course. For completness, and to show how easy it is to add animations to components, the code that runs the animation when you click the sliders background (and thus set its value) is:

AnimationManager.instance.run(getClassProperty("animation.pos"),
                              ["target" => this],
                              ["pos" => value]);

Finally, Iive also updated all the demos on http://haxeui.org/v2 to use these system wide animations, but I should probably note that ive used a “bounce” animation and that I have no intention of actually using this in the final released version of HaxeUI2. Im not sure if the default will have animations on or off yet (im leaning towards “off” with an ability to set groups of properties easily to turn them “on”) 




Add a comment Send a TrackBack