Holiday Animation

Put on your 3D Glasses to watch an animation of my final project:

There's also a non-anaglyph version if you don't have 3D glasses with you.

Holiday Cards

I put a lot of work into this project. Part of that is because I was super-enthusiastic about this idea, but also because there was a compatibility with another project outside of ITP that is important to me. And that project is designing my own holiday cards.

holiday greeting card that says "Happy Holidays" across the front and shows snowflakes falling from the sky

The deeper purpose of this is to make holiday cards that are more engaging than the generic holiday cards people send each other today. Holiday cards are supposed to be about expressing sincere appreciation for the people in your life but often that isn't what actually happens. By getting people to pay attention to the card and something I've made, I can build a deeper connection with them.

In previous years I've employed the 3D theme but also have made connect the dots puzzles. There are animations for 2013, 2014, 2015, 2016, 2018 if you are interested.

Technical Details

The animation was created in the Java version of Processing. I used the Camera3D library to make the ordinary 3D processing sketch into an anaglyph using the Dubois Anaglyphs algorithm.

The font morphing comes from JavaScript using the opentype.js and flubber libraries we learned about in class. Building on the work from my previous assignment I wrote JavaScript code that morphs every relevant letter into every valid snowflake and saves the morph data in JSON files that are later read by the Java code. The Java code uses these JSON data files to draw each letter-snowflake as needed during the animation.

The most interesting thing about the animation is that the output as created by my code is this:

The easiest approach for coordinating the morphing of snowflakes into letters and words is to avoid the problem entirely and animate the entire project in reverse. Instead of having the snowflakes descend from above, everything rises up from below and disperses randomly into the sky. When I do it this way I don't need to choreograph morphing snowflakes aligning themselves at precisely the right time to form words.

After inverting the flow of time this project actually becomes a straightforward application of the content of Dan Shiffman's book The Nature of Code. Refer to chapter 4 of his book. Consider each of the shapes or "particles" employed in this animation: letters, snowflakes and words. Programming each of them to rise up from the bottom of the screen and move around randomly is easy with the noise function. After programming each one individually I just had to put them together into one animation and get them to do their thing.

The source code is available on GitHub if you are interested.

Even More Technical Details

Letters like 't' and 'm' that can be drawn with one contour can morph into snowflakes that also have one contour. Letters like 'y' or 'd' that in this font have a hole in them are morphed into snowflakes that also have a hole in them. This was done to improve the morphing results and avoid having to separate or combine shapes. The JavaScript code finds every valid letter-snowflake pairing and morphs each in 2% increments from 0% to 100%.

Observe the behavior of characters like 'i' and 'F'. In the font I am using for the text both are drawn with two separate contours. The 'i' obviously has a dot and a base, and in this font the 'F' is a fancy F with the top part separate from the rest of the letter. These characters are formed from two separate snowflakes that land on top of each other and morph to form the complete letter.

Although the Java language does have a built-in JavaScript engine I ran this JavaScript code though the P5 web editor. I originally tried to run it through node but I got some crazy error in the flubber library. The JavaScript code and function input were exactly the same but executed differently in node. Can I not expect JavaScript to be the same from platform to platform??? I was very frustrated by this and tried different node versions to get it to work. Eventually I gave up and ran it through the P5 editor so I could move on.