BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Bridging the Gap Between Gesture and Animation with Facebook's Pop Framework

Bridging the Gap Between Gesture and Animation with Facebook's Pop Framework

This item in japanese

Facebook has recently open-sourced Pop, the animation engine behind its iOS Paper app. Pop aims at making it easier for developers to go beyond fire-and-forget animations, thus enabling interactive animations. In addition to static animations, Pop supports spring and decay dynamic animations, as well allowing the creation of custom animations.

Facebook Pop Engine Spring and Decay animations

According to Kimon Tsinteris (co-founder of Push Pop Press, which Facebook acquired in 2001), among the creators of Facebook's Paper app, one of the main motivations behind Pop was enabling direct manipulation of on-screen elements in a physically realistic way. Chris Eidhof and Florian Kugler, dissecting Interactive Animations in a Objc.io article, recall the strong effect that scrolling through a table had on the audience at the original iPhone presentation in 2007. They also suggest that there are very little apps today that embrace the direct manipulation paradigm and allow for animations that can be interacted with while they are running or interrupted. Examples of fire-and-forget animations in iOS are the animations opening and closing groups on the home screen, and the navigation controller animations. On the other hand, Apple Passbook app offers an example of realistic, interactive animations.

Facebook's Brian Amerige outlined very clearly the complexity of bridging the gap from user gestures to realistic animations. The key point is preserving the user's intent at the very end of a gesture by seeding the subsequent animation with the gestural velocity. By doing so, the animation can follow and complete the gesture in a realistic and fluid way.

Core Animation, the layer-based animation engine of iOS, does not natively support specifying the start velocity of an animation. So, if you try to interact with an animation created with Core Animation default API, the animation will exhibit a discontinuous velocity curve.

The issue with interactive animations

With iOS 7, Apple introduced the animation framework UIKit Dynamics (see WWDC 2013 sessions 206 and 221), based on a pseudo-physics engine that can animate everything that implements the UIDynamicItem protocol. According to Eidhof and Kugler, though this framework is very powerful and enables complex behaviors, its API can seem a bit overwhelming for the kind of animations that are generally needed in user interfaces.

Pop, on the other hand, strives to make things as simple as possible. A salient trait in Pop is indeed the fact that its API closely resembles the Core Animation API, which is long known to iOS developers. So, Pop's API allows to create a new animation in a very similar way to Core Animation:

    POPSpringAnimation *spring = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerRotation];
    spring.velocity = [NSValue valueWithCGPoint:velocity];

    [viewToAnimate.layer pop_addAnimation:spring forKey:@"rotationAnimation"];

This short example allows to add a bouncy effect to a UI element rotation and could be used at the end of a rotation gesture controlled through a UIPanGestureRecognizer:

- (void)panHandler:(UIPanGestureRecognizer *) panGesture {

    if (panGesture.state == UIGestureRecognizerStateEnded) {

CGPoint velocity = [recognizer velocityInView:self.view];

        POPSpringAnimation *spring = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerRotation];
        spring.velocity = [NSValue valueWithCGPoint:velocity];

        [viewToAnimate.layer pop_addAnimation:spring forKey:@"rotationAnimation"];

               
    } else {

        //-- transform the layer as per your gesture logics
    }
}

Besides the initial velocity, Pop allows to define a few more parameters specific to a spring animation, such as to simulate the spring tension, friction, and elasticity.

Although its API is inspired by Core Animation, Pop is not constrained to animating just those CALayer properties that are defined as animatable. In fact, Pop extends Core Animation animatable properties and the same API used to animate CALAyers can be also used to animate UIView's, UINavigationBar's, and UITabBar's properties. The most intriguing aspect of this is that, given Pop's open nature, it is possible to add more animatable properties on more classes. A full listing of all animatable properties supported by Pop currently can be found in the POPAnimatableProperty.h header file.

The basic mechanism by which Pop creates its magics is by handling all the animation logics on its own relying on a CADisplayLink to provide the beats to the animation.

One drawback of this approach, common to UIKit Dynamics, as Andy Matuschak pointed out, is that the CADisplayLink runs at the same priority as the app, while the render server handling UIView and CAAnimation animations runs at a higher priority, and thus is less likely to be affected by other tasks running on the system.

Rate this Article

Adoption
Style

BT