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 propertyValuesHolder
s within the objectAnimator
to manipulate the scale and translate attributes as the animation funs, and use keyframe
s 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 propertyValuesHolder
s 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 keyframe
s within propertyValuesHolder
s 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.