Search code examples
iosiphoneanimationcore-animationcalayer

Comprehend pause and resume animation on a layer


I am studying Animation in Core Animation Programming Guide and I get stuck on comprehending pause and resume animation on a layer.

The document tells me how to pause and resume animation without clear explanation. I think the key is to understand what is timeOffset and beginTime method of CAlayer.

These code is pause and resume animation. In resumeLayer method, layer.beginTime = timeSincePause; this line really make me confused.

-(void)pauseLayer:(CALayer*)layer {
   CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
   layer.speed = 0.0;
   layer.timeOffset = pausedTime;
}

-(void)resumeLayer:(CALayer*)layer {
   CFTimeInterval pausedTime = [layer timeOffset];
   layer.speed = 1.0;
   layer.timeOffset = 0.0;
   layer.beginTime = 0.0;
   CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
   layer.beginTime = timeSincePause;
}

Any help will be appreciated.


Solution

  • In the header file of CAMediaTiming, we can see these codes:

    /* The begin time of the object, in relation to its parent object, if
     * applicable. Defaults to 0. */
    
    @property CFTimeInterval beginTime;
    
    /* The basic duration of the object. Defaults to 0. */
    
    @property CFTimeInterval duration;
    
    /* The rate of the layer. Used to scale parent time to local time, e.g.
     * if rate is 2, local time progresses twice as fast as parent time.
     * Defaults to 1. */
    
    @property float speed;
    
    /* Additional offset in active local time. i.e. to convert from parent
     * time tp to active local time t: t = (tp - begin) * speed + offset.
     * One use of this is to "pause" a layer by setting `speed' to zero and
     * `offset' to a suitable value. Defaults to 0. */
    
    @property CFTimeInterval timeOffset;
    

    What important is the formula:

    t = (tp - begin) * speed + offset

    This formula defines how the global time (or parent time, tp) maps to the local time of the layer. And this formula can explain everything of the listed codes:

    1. At time A, the animation is paused. After sets the speed = 0, and timeOffset = pauseTime, the local time of the layer is equal pauseTime. And local time will not increase any more because speed = 0;
    2. At time B, the animation is resumed. After sets the speed = 1.0, timeOffset = 0, beginTime = 0, the layer's local time is equal to the global time (or tp) which is (timePause + timeSinacePause). But we need the animation starts from the time point #A, so we set the beginTime = timeSincePaused, and then the layer's local time is equal to timePause. Of cause, this incurs the animation continue from the point paused.

    enter image description here