Animation in Webix UI

While providing many UI options, Webix is quite short of animations. It can be easily changed though. Let’s check how to add nice animation effects for different Webix controls.

Carousel, MultiView, TabView

TabView is one of two components that have a built-in support for animation. When you are changing the active tab, a new one is shown with some animation. You can use the animate property to configure the details of animation

Code of demo

Accordion

When closing or opening the panel of accordion, the UI of the widget switches to the new state immediately. It is fine for most cases. Still, it is not very user-friendly, as a user can lose the context after such a straight UI reconstruction. By adding animation to width and height changes, we will get a cute transition effect.

 .webix_accordionitem{
    transition:width 0.5s;
  }
  .webix_accordionitem.vertical{
    transition:height 0.5s;
  }

Code of demo

Tree

In the case of tree, animation can be applied to opening of tree branches. Adding some animation to this process gives a visual clue for the user and improves total usability.

While this modification looks pretty easy, it requires the most complex solution from all the described ones.
First we need to add the transition styling:

 .webix_tree_leaves{
    transition:height 0.3s;
    overflow:hidden;
  }

After that we need to add a code for opening and closing events which will replace the existing repainting logic with an attractive animation. Similar to specifying animation in accordion, it can be done for each instance separately or you can create a new view with a custom behavior. Let’s do it by the “per-instance” way:

webix.ui({
  view:"tree",
  select:true,
  data:tree_data,
  on:{
    onAfterOpen:function(id){
      var node = this.getItemNode(id);
      var height = node.nextSibling.offsetHeight;
      node.nextSibling.style.height = "1px";
      webix.delay(function(){
        node.nextSibling.style.height = height+"px";
      });
    },
    onBeforeClose:function(id){
      if (this._in_animation){
        this._in_animation = false;
        return true;
      }

      var node = this.getItemNode(id);
      node.nextSibling.style.height = "1px";

      webix.delay(function(){ this.close(id); }, this,[],300);
      this._in_animation = true;
      return false;
    },
  }
})

A lot of code for such simple tasks, but there’s no better way to do it.

In the onAfterOpen handler we are setting the starting height which changes to the actual height after a small delay. It is necessary to trigger the animation.

In the onBeforeClose handler we block the default repainting operation and change the height of a branch instead, which will trigger the animation. After some delay the code calls the close method for the second time to repaint the closed branch.

Window

Window control has a partial animation support by default. When you use position:top, a window control will slide down from the top of the browser:

Custom animation effects can be added by using the onShow and onHide events. You can attach custom handlers for each window control or create a custom class of windows with necessary animation.

webix.protoUI({
  name:"ani-window",
  $init:function(){
    this.$ready.push(function(){
      this.attachEvent("onShow", function(){
        var base = this.$view.className.split("animated")[0];
        this.$view.className = base + " animated fadeInUp";  
      })
      this.attachEvent("onHide", function(){
        this.$view.style.display = "block";
        this.$view.className += " animated rollOut";  
      })
    });
  }
}, webix.ui.window);

This code creates a new control ani-window that works the same as a usual window, but it appears and disappears with a nice animation. Try the demo below.

The fadeInUp and rollOut css classes are taken from animate.css – one of the free animation libraries. You can use any other style of animation supported by animate.css: fading, rolling, bouncing, etc.

Pay attention that it will work only if you have animate.css included on the page.

Button

The trick with animate.css can also be applied to buttons:

  { view:"button", value:"Click me", id:"add_button", click:function(){

      webix.html.addCss( $$("add_button").$view, " animated bounce" );
      setTimeout(function(){
        webix.html.removeCss( $$("add_button").$view, " animated bounce" );
      },1000);

    }}

Here we have a button that will animate itself after clicking. The addCss command adds the animation style and the removeCss command cleans that style, so the button will be ready for the next click and next round of animation.

Code of demo

Animating Data and Views

You can use animate.css to add some kind of animation to any Webix view.
To animate the whole view, you can use the $view property the same as in the button example above.

{ view:"button", value:"View", click:function(){
  webix.html.addCss( $$("tree").$view , "animated swing");
}}

If you need to animate just a single item in the component, you can use the combination of the getItemNode and addCss API:

{ view:"button", value:"Item", click:function(){
  webix.html.addCss( $$("tree").getItemNode(1) , "animated flash");
}}

or the addRowCss API:

{ view:"button", value:"Row in table", click:function(){
  $$("grid").addRowCss(2,"animated flash");
}}

I can’t imagine many cases where it may be necessary to animate the whole view. At the same time, animating separate items can be useful to bring users’ attention to some specific element.

Code of demo

What else?

The above examples cover most of animation scenarios which you can encounter in real life apps. Even if you find some other use-cases, the techniques described above can be adapted nearly for any scenario. You can use subclassing and event handling to define new behaviors and apply animate.css, effect.css or any other CSS animation library for an actual animation.

If you have some additions or face some problems with the described techniques, feel free to share them in comments.