Search code examples
ioscore-animation

CATransform3DMakeRotation animating trough zero (from -45 to +45 angle)?


I'm trying to do a simple horizontal flip animation with a bounce effect.

    [UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationCurveEaseIn animations:^{
    front.layer.transform=CATransform3DMakeRotation(DEGREES_TO_RADIANS(90), -1.0,0.0,0.0); // flip halfway
}
completion:^(BOOL finished) { // swap view
    front.alpha=0;
    back.alpha=1;
    [UIView animateWithDuration:0.5 animations:^{ // flip remaining + bounce
        back.layer.transform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(45), 1.0,0.0,0.0); // final + 45 
    }
    completion:^(BOOL finished) {
        [UIView animateWithDuration:0.25 animations:^{
            back.layer.transform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(-22.5), 1.0,0.0,0.0); // bounce back
        }
        completion:^(BOOL finished) {
            [UIView animateWithDuration:0.125 animations:^{
                back.layer.transform = CATransform3DMakeRotation(0, 1.0,0.0,0.0); // final
            }];
        }];
    }];
}];

Works well except for the 'bounce'. The -22.5 rotation transitions to 0 and than back to 22.5 instead of continuing to -22.5.

I've tried various values and also including an intermediate nested block that transitions the bounce to '0' before going to negative. Didn't help. The rotation always animates to a positive instead of a negative angle.

Just as a test, changing the 'final + 45' to a negative angle does however stop the animation at the desired angle. So the angles themselves are ok.

Problem seems to be doing a 'counter clockwise' rotation starting from zero or going trough zero. Values smaller than zero than always get converted to a positive angle.

Independent if the above is the right technique for implementing a bounce effect, how would a (nested) layer animation be constructed that rotates via CATransform3DMakeRotation from a positive (45) to a negative angle (-45)?


Solution

  • You are rotating around the x-axis. Without a perspective on your transform, how would you see the difference between positive and negative angles? Without perspective, both positive and negative rotations look the same (the decrease the height). You can apply perspective to your transform by changing the value in the third row and fourth column of your transform matrix by setting .m34. Search for "Core Animation perspective" and you will find a good explanation.

    I ran your code above (on a simple view, filled with orange). To more easily be able to see the rotation and the difference between positive and negative angles, I changed it so that it rotates around the z-axis.

    These are four screenshots that I took during the animation. As you can see, the negative angle works, unless I misunderstood what you were trying to do.

    0 degrees 45 degrees -25 degrees 0 degrees