Animating on the Apple Watch
This is a repost of an article I wrote for the company I work at, Tumult.
Subtle animations are a great way to add fun and personality to an Apple Watch App. Whether its a custom loading indicator or part of a game, animations can bring your watch app to the next level. To add an animation you simply need to create a png image sequence and tell an Image or Group to start animating.
Hype can greatly simplify the process of creating image sequences by allowing you to build complex keyframe based animations and export them as image sequences.
When creating an image sequence for a watch app here are a few tips to keep in mind:
- Apple has strict limits on how large your watch app can be (currently 20 MB), so keep your animations simple and optimize your images (more on this later)
- Store animations locally on the watch so they load quickly
- The 38mm and 42mm displays are different sizes, but try to use the same image sequences on both whenever possible to save space
- Don’t forget that WKInterfaceGroups support animated background images, you can use groups to create layered animations
Creating Image Sequences
There are many ways to create image sequences. I am going to walk through a quick example that uses Hype to create a loading indicator for a watch app.
Download the Hype Document here: Loading.hype
Tips for building watch animations with Hype:
- The Apple Watch has a retina display so build your animations at 2x size
- If you want your animation to run at 30 fps images will add up quickly so try to keep your loop duration short
- Run your animations through a tool like ImageOptim to reduce file size
After finishing your animation go to File->Export as Movie->PNG Image Sequence.
This will create a folder containing the images numbered sequentially. You will need to rename the images so the names are formatted in the way the Watch SDK expects (<name><number>@2x.png). I created a quick Automator workflow (RenameImagesForAppleWatch.workflow) to simplify renaming. Just run the workflow and select all your images.
In this example the loop duration is 3 seconds so we end up with 90 images totaling 1.1 MB. Running these images through ImageOptim reduces the size to 639 KB.
Adding an image sequence to your Xcode project
Add the images to an xcassets folder in the WatchKit App target in Xcode. Make sure to add them to the WatchKit App so the images will be stored locally on the watch allowing the animation to load quickly.
Next add a WKInterfaceImage (or WKInterfaceGroup) to your Interface storyboard and fill in the Image name. You can either have the image start animating immediately or tell it to start animating later programatically. To have it animate on load set Animate to YES, fill in the duration and check ‘Animate on Load’ in the storyboard.
To start the animation later just call -[WKInterfaceImage startAnimating] or -[WKInterfaceImage startAnimatingWithImagesInRange:duration:repeatCount:].
Animating in Apple Watch Games
While experimenting with png image sequence export in Hype we realized we could build a fun little watch game by creating sets of image sequences and switching between these sets as a result of user interaction or changes to the game state.
We ended up building Pastime Baseball. In Pastime baseball you have one inning to score as many runs as possible. The pitch starts automatically and you tap to swing. The better your timing the better the hit.
For this game we pre-rendered all possible animations for the offensive player, the defensive players, and the ball. These images are then layered on top of each other using WKInterfaceGroups.
Initially we created all the animations for Pastime in Hype. This allowed us to quickly prototype our ideas and create a proof of concept. As we added more game states and wanted to try out more realistic 3D perspective and physics we eventually switched to generating the image sequences programatically.
Since all 3rd party developer code runs on the iPhone we built a state machine that tells the watch when to switch between animation sets. These changes can be the result of a user tapping to swing, or because of game state changes such as a player needing to advance to the next base.
While the watch is capable of running a single animation at a high frame rate we found that there can be a delay when switching from one animation sequence to another. This delay appears to be largely dependent on the number of images in the sequence and the size of the images. After some testing and optimizations we were able to get a pretty consistent frame rate when we set our animations to run at 8 fps and kept each image sequence below 20 images.
Because each offensive player is in a separate layer we were able to reuse many of the image sequences. This and the fact that we reduced our frame rate to 8 fps allowed us to keep the app size small. In the end Pastime Baseball only takes up 1.5 mb on the watch.
Building an action game for the Apple Watch was a fun exercise in pushing the initial watch SDK to its limits. It will be fun to see what Apple announces next week at WWDC!