Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keyframe animation key time

I've just created a keyframe animation like this:

[UIView animateKeyframesWithDuration:10 delay:0 options:0 animations:^{
    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:.1 animations:^{
        view.alpha = 0;
    }];
} completion:nil];

And this is a CAKeyframeAnimation that gets created:

(lldb) po [self.layer animationForKey:@"opacity"]
<CAKeyframeAnimation:0x10a6364b0; keyTimes = (
    0,
    "0.1",
    1
); values = (
    1,
    0,
    0
); calculationMode = linear; delegate = <UIViewKeyframeAnimationState: 0x10a6358d0>; fillMode = both; timingFunction = easeInEaseOut; duration = 10; keyPath = opacity>

Question:

The entire animation should take 10 seconds with the opacity animating for 10 * 0.1 = 1 second, right? When I look at the animation, the change is being animated way longer than 1 second.

Why?

like image 361
Rudolf Adamkovič Avatar asked Dec 11 '13 14:12

Rudolf Adamkovič


People also ask

How many seconds is a keyframe?

For an example of how keyframe intervals work, if your interval is set to every 2 seconds, and your frame rate is 30 frames per second, this would mean roughly every 60 frames a keyframe is produced.

How long is a keyframe?

For example, a key frame may be output once for each 10 seconds of video, even though the video image does not change enough visually to warrant the automatic creation of the key frame. That would allow seeking within the video stream at a minimum of 10-second intervals.

How do you keyframe in an animation?

To insert a new frame, select Insert > Timeline > Frame (F5). To create a keyframe, select Insert > Timeline > Keyframe (F6), or right-click (Windows) or Control‑click (Macintosh) the frame where you want to place a keyframe, and select Insert Keyframe from the context menu.

How do I show keyframes in timeline?

In the upper-right corner of the Timeline in Motion, click the Show Keyframes button so that it's highlighted blue. Any applied keyframes appear in the track area as small red (or white, when selected) diamonds beneath the object they animate.


1 Answers

The reason is that the animation's timing function is not linear.

“Time and space are relative concepts.” – Theory of relativity

Layer and animations use a hierarchical timing system, where each object has its own local time which is dependant of its parents and its own timing parameters.

For instance, animations have a timing function that defines their pacing. The default timing functions for an animation created by UIKit is the ease-in ease-out timing function which defines a timing that begins slowly, accelerates through the middle of its duration, and then slows again before completing. It makes for smooth animations that don't start or stop abruptly. However it will also temper with the key times of your keyframe animation which is annoying when you need precise timing.

You can disable the ease-in ease-out timing by passing the UIViewAnimationOptionCurveLinear option to the animateKeyframesWithDuration:delay:options:animations:completion: method. I'm not sure whether it's intended as you need to cast the value from UIViewAnimationOptions to UIViewKeyframeAnimationOptions and the documentation does not say anything about that. Maybe a better (but more verbose) way is to embed the keyframe animation block inside a standard animation block like this:

[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
    [UIView animateKeyframesWithDuration:0 /*inherited*/ delay:0 options:0 animations:^{
        [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:.1 animations:^{
            view.alpha = 0;
        }];
    } completion:nil];
} completion:nil];
like image 86
Nicolas Bachschmidt Avatar answered Oct 19 '22 04:10

Nicolas Bachschmidt