Joyful animations using arcs
From tweet to polished animation
The following tweet inspired me to finish an animation I had planned for one of my apps. The end result was better than I expected.
In Emoji Stickers, every time you select an emoji they fly into your canvas. This animation was just a straight line from point A to point B. There was nothing wrong with it, but always felt kind of stiff. Using curves, we can do better.
The code
I knew what I needed to do, I remember watching a WWDC video a while ago about CAKeyframeAnimation
and using paths to animate along a given area. I was surprised that the implementation was actually very simple.
That is literally all, of course you need to tweak your timing functions, duration, etc to really polish it. But I will ignore that for this article and focus on the challenging bit, that second line. How can I draw this line? And more importantly, how can I debug it?
Drawing the path
I knew I wanted to add a curve into the translation of the view, changing the view origin wasn’t going to be enough anymore. Enter UIBezierPath
and the delightful addQuadCurve
function to literally do just want we need.
The final implementation looks like this:
If we breakdown the previous code snippet, you will find two (2) main themes: finding the points, and drawing a small curve between
Finding the origin and final destination of the curve.
Knowing the two points: the origin being the starting position of the emoji, and the destination the exact centre of the canvas. Now, all I needed to do is create a CGRect
between the two points (this little rectangle will come handy in the next step)
With this information, the next step is to draw the line.
Plotting a small curve between the points
Drawing a curve between the two positions requires a control point which apple describes as follows:
The control point of the curve.
Not great 🙃, thankfully they have a nice illustration that is more helpful.
We find such point using our previous rectangle:
By randomly choosing between the bottom and top of the rectangle and assign that as the Y coordinate, and then choosing the middle of the rectangle as the X coordinate. We create a small amount of playfulness to the animation by giving at least two (2) variants.
Debugging the path
This was all great in paper, but how can we debug the rectangles, lines, and curves we are drawing? We probably have multiple choices, but I went with the most simple ones I could think of: using the debugger with quick look, and drawing them out to the app for better visualization.
Using the debugger was the easy part, we need to put a breakpoint in place right after we define our path and once the runtime stops there, simply click on it to see more information.
The most difficult but totally “tweetable” solution, was to draw the paths on screen every time we add something. That can be achieved with the following code snippet:
Technically, all of them could be CAShapeLayers
but I started with a UIView
for some reason 😅. As you can see, we create a view representation of the rectangle between the two points, and finally add a layer
to the canvas with the shape of the path we constructed.
Seeing it all together
That is all, and the best part is how it looks! This was probably one of the quickest wins I had in this project while still having a great impact.
Further reading
That is all!, as always you can find the full source code on GitHub https://github.com/raulriera/technical-articles