Animation / Custom / View

Snowfall

Ho, ho, ho. ‘Tis the season to be jolly, and all that malarkey. As the publication date for this post is Christmas Day 2015, it seems only fitting that we should cover something festive on Styling Android. For those reading who do not celebrate Christmas, and those who are reading this post in June – please accept my apologies.

So, the big question is: What can we do that encapsulates the spirit and true meaning of Christmas? The obvious answer to that question is: A picture of your truly wearing a Christmas hat:

tree

As you can see I’m exuding Christmas cheer!

While I feel that picture alone is worthy of a mic drop ending to this post, I’m feeling generous so let’s actually make it snow as well.

We can do this by adding a custom View to a layout containing the image:

Although there is a temptation to do this in a single custom view which extends ImageView, I have elected to keep them separate so that we can invalidate SnowView for each animation frame and not re-render the image each time.

So let’s take a look at our custom View:

This is fairly straightforward. When the View is resized we initialise it with 150 SnowFlake objects which will be randomly positioned. The onDraw() method draws all of the SnowFlake objects and then schedules an invalidate() which will be called after a short pause so that we don’t completely hog the UI thread.

The SnowFlake code is very loosely based upon the snowfall algorithm by Samuel Arbesman:

When each SnowFlake is initialised it is placed in a random position on the Canvas. This is to ensure that when the snow is first drawn it appears that the snowfall is already in progress rather than starting if we were to start all of the flakes from the top. When a flake goes out of the Canvas bounds, it is re-positioned to a random horizontal location at the top – so we re-cycle our flakes to avoid unnecessary object creation.

When each frame is drawn, we first move the SnowFlake by adding some random elements to simulate small gusts of wind which could cause individual flakes to change direction slightly. We then perform our in bounds check (and move it back to the top, if necessary) before actually drawing the SnowFlake on the Canvas.

All of the constant values were tweaked until I found a snowfall simulation that I was happy with.

So when we run this we get the following:

Of course drawing to a Canvas is not the most performant way of rendering stuff like this (such as rendering using OpenGL) but, quite frankly, I have presents to open and turkey to eat so it can wait until another time. See ya!

The source code for this article is available here.

Part of this code is based upon “Snowfall” by Sam Arbesman, licensed under Creative Commons Attribution-Share Alike 3.0 and GNU GPL license.
Work: http://openprocessing.org/visuals/?visualID= 84771
License:
http://creativecommons.org/licenses/by-sa/3.0/
http://creativecommons.org/licenses/GPL/2.0/

© 2015, Mark Allison. All rights reserved.

CC BY-NC-SA 4.0 Snowfall by Styling Android is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Permissions beyond the scope of this license may be available at http://blog.stylingandroid.com/license-information.

Leave a Reply

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