Search code examples
iosswiftcashapelayercabasicanimation

iOS morphing play/pause animation


I would like to have a YouTube like morphing play/pause animation in the app I am developing. It looks like the animation here. I am not sure how to go about it. I know I need a CABasicAnimation and CAShapeLayer. I know I need two (or maybe more?) UIBezierPath-s. One will be the path of the shapeLayer, the other one the toValue of the animation. Something like:

shape.path = pausePath().cgPath

let animation = CABasicAnimation(keyPath: "path")
animation.toValue = trainglePath().cgPath
animation.duration = 1
shape.add(animation, forKey: animation.keyPath)

But I am not sure how to go about these paths. I have the following questions:

  1. Is the way the path is made important? For example will a line drawn from left to right be animated differently than a line made from right to left? I mean something like path.move(to: startPoint); path.addLine(to: endPoint1) opposed to path.move(to: endPoint1); path.addLine(to: startPoint)
  2. Will two paths be enough? One for the start button and one for the pause button? If yes - what is the proper way of drawing them so that they animate "correctly"? I don't ask for code here (not that I mind having code as an answer) but some general explanation will be enough for starters.

Solution

  • The key thing to get path animations to work is for both the starting and ending path to have the same number of control points. If you look at that animation it looks to me like the initial "play" triangle is drawn as 2 closed quadrilaterals that touch, where the right quadrilateral has 2 of it's points together so that it looks like a triangle. Then the animation shifts the control-points of those quadrilaterals apart and turns them both into the rectangles of the pause symbol.

    If you map that out on graph paper it should be pretty easy to create the before and after control points.

    Consider the (very crude) illustration below. The top part shows the "play" triangle divided into 2 quadrilaterals, and shows the right part (in yellow) as a quadrilateral with the points on its right side separated slightly to show the idea. In practice you'd set up that quadrilateral with those two control points having the exact same coordinates.

    I labeled the control points for each quadrilateral using numbers to show the order of drawing them (For each quadrilateral: moveTo first point, lineTo 2nd/3rd/4th point, and finally a lineTo the first point, to close the polygon.)

    The bottom illustration shows the points shifted to give the pause symbol.

    If you create a CABasicAnimation of a CAShapeLayer starting with the control points like the top illustration and the end with the control points like the bottom illustration you should get an animation very much like the one you linked to.

    enter image description here

    I just created a demo program that creates an animation like what I described. Here is what it looks like:

    enter image description here

    I stroke the paths in black and fill them with cyan so it's easier to tell what's going on.

    (That is a little more finished than my hand drawing <grin>.)

    You can look at the project that generates that animation at this Github link.