Beware when using CSS Animation on a Telerik Platform App

I recently used Telerik Platform (http://www.telerik.com/platform) to build my first mobile game (Wah! http://www.ampzone.com/projects/wah). It was a bit of an experiment as I didn't know how well a game built with HTML, CSS and JS would work out on a mobile device. While I feel I have plenty of room for improvement, overall I think the test proved a success. I'm just going to write about one issue I had while attempting to improve the performance of the animations in my game. I had read that it was more efficient to use CSS animation rather than using JavaScript timers and jQuery Animations. Therefore, I decided I would use them wherever I could.

CSS animations felt like they naturally suited my need to remove certain objects (toys and broccoli) from the screen after a set amount of time. I wanted to have the objects flash in and out a few times before disappearing completely. This was relatively straight forward to achieve with the following:

body:not(.pause) .toy{  
    animation: ease-in;
    animation-name: blinkOut, blinkIn, blinkOut, blinkIn, removeItem;
    animation-delay: 8s, 8.4s, 8.8s, 9.2s, 9.6s;
    animation-fill-mode: forwards;
    
    -webkit-animation: ease-in;
    -webkit-animation-name: blinkOut, blinkIn, blinkOut, blinkIn, removeItem;
    -webkit-animation-delay: 8s, 8.4s, 8.8s, 9.2s, 9.6s;
    -webkit-animation-fill-mode: forwards;
}

And the animations I had simply changed the background position so that my sprites would display a faded out version of the object. Here is the code:

@keyframes blinkOut {
    to {
        background-position:0 0;
    }
}

@-webkit-keyframes blinkOut {
    to {
        background-position:0 0;
    }
}

@keyframes blinkIn {
    to {
        background-position:0 -45px;
    }
}

@-webkit-keyframes blinkIn {
    to {
        background-position:0 -45px;
    }
}

@keyframes removeItem {
    to {
        overflow:hidden;
        width:0;
        height:0;
        visibility: hidden;
    }
}

@-webkit-keyframes removeItem {
    to {
        overflow:hidden;
        width:0;
        height:0;
        visibility: hidden;
    }
}

I then had a JS function which was being called every second to act as a garbage collector. It would check if there were elements which were removed from display and, if so, remove the html for that element.

cleanUpItems:function(){
    var items = $( ".toy:hidden, .broccoli:hidden, .toast:hidden" );
    for (var i=0; i < items.length; i++) {
        var item =$(items[i]);
        if(item.height()==0){
            if(Draggable.get(item)!=null){
                //removes item as a draggable element
            	Draggable.get(item).kill();
            }
            item.remove();
        }
    }
    var sweets = $( ".sweet:hidden" );
    for (var i=0; i < sweets.length; i++) {
        $(sweets[i]).parent().remove();
    }
}

This seemed to work well, until I started testing on actual mobile devices instead of in the emulator. Issues varied slightly across devices, either it wouldn't flash or it became virtually impossible to interact with the element. I tried a few different options to fix this, but in the end I decided it was best to move back to JavaScript in this instance. I selected to use the GreenSock Animation Platform (GSAP https://greensock.com/gsap) as it has good reviews for performance compared to jQuery. It also easily fitted into my project technology stack and ended up becoming a valuable addition.

Here is the simple method I called whenever an object (toy in this case) was created.

animateToy:function(toy){
    var toyDisplayTime = 10;
    TweenLite.to(toy, 0, { delay:(toyDisplayTime-2), backgroundPosition:'0 -45px' });
    TweenLite.to(toy, 0, { delay:(toyDisplayTime-1.6), backgroundPosition:'0 0' });
    TweenLite.to(toy, 0, { delay:(toyDisplayTime-1.2), backgroundPosition:'0 -45px' });
    TweenLite.to(toy, 0, { delay:(toyDisplayTime-0.8), backgroundPosition:'0 0' });
    TweenLite.to(toy, 0, { delay:(toyDisplayTime-0.4), overflow:'hidden',height:0,width:0,visibility: 'hidden' });
}

CSS animations are the best option in many cases and for most websites they work incredibly smoothly, but unfortunately, this was a more unique situation that they just weren't compatible with. Although I'm sure it won't be long.