AnimatedIcons / Animation

Animated Icons: Info

There is a nice micro-animation library at useanimations.com which contains some useful animations which are particularly well suited for animated icons. These are all free to use and downloadable at Lottie animations. For those that already use Lottie they can use these animations as-is. However using them is apps which don’t use Lottie, or in cases where they may need tweaking and you don’t have a designer available that can perform the necessary tweaks in After Effects, it may not be possible to do this. In this occasional series we’ll look at how to create some of these animations as Animated Vector Drawables which will show some useful AVD techniques.

The icon we’re going to look at in this article is an information icon, consisting of the lowercase letter i inside a circle, and when the icon state is toggled the letter moves down and then zooms in. The basic techniques that we can use to achieve this are actually pretty simple and are things that we’ve looked at before in this series. However, there are a couple of subtleties which we haven’t looked at before which is what we’ll focus on in this article.

The first thing worth considering is the fact that as the letter i moves downward, part of it moves outside the enclosing circle, but is now displayed. There are actually a couple of different techniques that we could use to achieve this. Firstly we could animate the pathData so that it never draws outside the circle perimeter, but this would result in an animator that would require plenty of mathematical gymnastics plus a heap trial and error to get right. It would also be pretty fragile because changes to the timings of the various phases of the animation would affect what precise pathData would be required for any given frame when the animation is playing, and this is further impacted by the fact that there is a subtle over-shoot in the animation. During the first half of the animation, the only thing that is happening is that the letter i moves downward. But in the second half there’s a zoom in, and the letter i actually moves up again slightly. This adds a nice playful quality to the animation, but makes the technique of modifying the pathData to prevent the i from being drawn outside of the circle, a bit harder.

However, there’s another technique that we can use – a clip-path. We looked at clip-path back in this article albeit in a very different way. As a quick recap: A clip-path defines a region within which subsequent operations will be drawn, but nothing will be drawn outside of the clip path. If we look at the starting, zoomed out state we can see the clip-path which uses identical pathData to the circle which precedes it:



    

    

    
        
    

So first the circle is drawn without any limitations because the clip-path has not been applied yet, then we declare the clip-path which restricts all subsequent operations from painting outside of the circle, and then we draw the letter i. At present this falls entirely within the circle, but the clip-path will do its magic once we start animating things.

Another important thing here is that we have enclosed the path element which draws the letter i within a group that we’ve named letter_i. It is this group that we’ll animate to move and zoom, but it is worth mentioning that the clip-path will affect this group and any children it has because it a sibling of the group. If we were to move the clip-path inside this group, it would only affect the children of the group which follow it. It would not affect any operations which occur outside of the group so it is possible to limit the scope of a clip-path by enclosing it in a group.

In this case we have it outside the group because we only want the animations that we perform on the group to affect the letter i and not the clip-path which matches the circle that was drawn earlier.

If we look at the end state, we can see that a translateY is used to move the letter i downwards, and a scaleX and scaleY are used to perform the zoom in:



    

    

    
        
    

The pivot point that we set on this group will mean that scaling will occur from the centre point of the icon.

So let’s take a look at the animator for this:



    
        
        
        
    

    
        
        
        
    

    
        
        
        
    

We use propertyValuesHolders within the objectAnimator to manipulate the scale and translate attributes as the animation funs, and use keyframes within each propertyValuesHolder to control when during the animation the values change.

Let’s first look at the final propertyValuesHolder which controls the translateY attribute which is responsible for the vertical movement of the letter i. At the start point (<keyframe fraction="0" .../>) this value is set to 0 so no positional offset will be applied. At the halfway point (<keyframe fraction="0.5" .../>) this value is 18 which means that over the first half of the animation, the letter i will move down by 18 units. At the end point (<keyframe fraction="1" .../>) this value is 16 which means that in the second half of the animation the letter i moves back upwards by 2 units, and that gives the small bounce effect that we discussed earlier.

The other two propertyValuesHolders are both identical other than the fact that they operate on different properties – scaleX and scaleY. They both start with a scale factor of 1 which is held at that value until the half way point, after which they rise to 2, so no scaling is performed in the first half of the animation, but that only happens in the second half.

Using keyframes within propertyValuesHolders are a really useful trick for achieving multi-phased animations in a single objectAnimator.

The line widths of the path which are doubled because of the scaling and enforce the illusion that we are zooming in. It is important to understand this when using scaling. If changes to the line width are not required, then it will be necessary to add an animator to the strokeWidth attribute of the path to alter it in parallel with the scaling. In this case, we would hold the strokeWidth at 5 for the first half of the animation, and then animate between 5 and 2.5 over the second half. This would effectively cancel out the line scaling that the scaleX and scaleY while allowing the other changes (such as the distance between the main body of the letter i and the tittle (that’s what the dot is named) would still change according to the scaling.

This animation is another great example of how structuring our vectors to meet the animation requirements enables us to use much simpler animation techniques to create visually pleasing results.

The source code for this article is available here.

© 2020, Mark Allison. All rights reserved.

Copyright © 2020 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.