AnimatedIcons / Animation / Uncategorized

AnimatedIcons: Heart

There is a nice micro-animation library at useanimations.com which contains some useful icon animations. These are all free to use and downloadable at Lottie animations. For those that already use Lottie they can use these animations as-is. It may not be possible to use them in apps which don’t use Lottie, or if there’s no designer that can tweak things. In this occasional series we’ll look at how to create some of these animations as Animated Vector Drawables. We’ll also showcase some useful AVD techniques.

This time we’re going to look at a heart shape. The checked state is a filled heart and the unchecked state is an empty heart. The transition between the two states involves the outline pushing inwards and out again. With the fill appearing to grow within the outline.

The first thing we’ll look at is how to draw the heart shape in SVG path data. While we’ve looked at a technique to draw a heart shape previously on Styling Android, that was a masking technique for Canvas and isn’t what we need here – we need to draw the outline. That isn’t actually too difficult using a combination of SVG commands.

Drawing the heart

We start by positioning the pen on the left in the vertical centre of the 64 x 64 canvas: M12,32. Next we draw a semi-circle to the top centre of the shape – the dip in the top of the heart: A8,8 0 0 1 32, 18. I won’t bother explaining the arc command here, for those unfamiliar with it there’s a detailed explanation here. This gives us the top left curved section of the heart:

Next we draw a second, similar arc to the right vertical centre – the mirror point of where we started: A8,8 0 0 1 52, 32 which gives us the top right curved section of the heart:

Now we draw a straight line to the bottom centre: L 32, 56 which gives us the right bottom line:

All that remains is to draw the final line which can be achieved using a closepath command – which draws a straight line from the current point back to the start point of the path: z. This completes the heart shape:

We achieve the nice rounded corners by specifying android:strokeLineJoin="round" on our path element, and that softens the sharp corners where the lines meet. There are actually two paths using the same path data, but one just has the outline drawn, whist the other is filled. We also wrap each of these inside a separate group each of which has a pivot point set in the centre of the canvas which will become important when we come to animate things:



    
        
    

    
        
    

It’s worth noting that the filled group is scaled to 0, and the filled path has a fillAlpha of 0, so the filled section is not actually visible. However we now have things set up to enable us to perform the animations.

Animating things

To animate the push in then out of the outline, we perform a scale on the group which contains the outline path:



    
        
            
                
                    
                    
                    
                
                
                    
                    
                    
                
            
        
    
    .
    .
    .

We use a propertyValuesHolder to animate both scaleX and scaleY in exactly the same way so that we get a symmetrical scale change. We start at 100% scale, reduce to 80% scale at the half way point, and then return to 100% at the end. Thanks to the pivot point we set in the groups that we created in the VectorDrawable XML.

Next we need to fade in the filled shape:


    .
    .
    .
    
        
            
                
                    
                    
                    
                
            
        
    
    .
    .
    .

Here we hold the value at 0 until we’re half way through the animation. We then increase it to 1 during the second half of the animation. This gradually fades the filled background in as the outline is pushing back out again. However this will not actually display anything because of the scale that we applied to the group containing this in the VectorDrawable XML. So we also need to animate the scale of the filled shape:


    .
    .
    .
    
        
            
                
                    
                    
                    
                
                
                    
                    
                    
                
            
        
    

Once again we use propertyValuesHolders to animate both scaleX and scaleY but this time we hold both values at 0 until we’re half way though the animation, and then increase them both to 1 during the second half of the animation.

The combination of the scale and alpha animations give the illusion that the shape is growing and appearing from nowhere. They’re both offset to the second half of the animation so they only happen as the outline shape is expanding. This is following the the push in during the first half of the animation.

We create a complementary animation for the transition from checked to unchecked states. For this we start with the filled shape fully visible and a scaled to 100%. Then we reduce the alpha and scale to 0 during the first half of the animation. This happens along with the same push in and out of the outline. I won’t include the it here, but it’s available in the source code.

The combination of these animations gives us quite a pleasing effect:

There’s nothing groundbreaking in terms of the individual animation techniques that we’ve used here. But the important thing is how we choreograph the individual animations to create something more complex than the individual animations. Oh, and we learned how to draw a heart shape along the way!

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.