CABasicAnimation使NSView翻转

Hol*_*bæk 9 objective-c calayer cabasicanimation caanimation ios

我正在制作一款适用于Mac的纸牌游戏,而我正在使用CABasicAnimation来使卡片翻转.它几乎可以工作,但可能会更好一些.

当它现在工作时,卡片向内翻转(向左) - 屏幕截图1.当卡片"向上翻转"一直向左移动时,我更改了NSView的图像并再次将卡片向外翻转 - 屏幕截图2.

截图1(翻转):

截图1

截图2(翻出):

截图2

翻阅代码:

- (void)flipAnimationInwards{
    // Animate shadow
    NSShadow *dropShadow = [[NSShadow alloc] init];
    [dropShadow setShadowOffset:NSMakeSize(0, 1)];
    [dropShadow setShadowBlurRadius:15];
    [dropShadow setShadowColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.5]];
    [[self animator] setShadow:dropShadow];

    // Create CAAnimation
    CABasicAnimation* rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    rotationAnimation.fromValue = [NSNumber numberWithFloat: 0.0];
    rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI/2];
    rotationAnimation.duration = 3.1;
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    rotationAnimation.fillMode = kCAFillModeForwards;
    rotationAnimation.removedOnCompletion = NO;
    [rotationAnimation setValue:@"flipAnimationInwards" forKey:@"flip"];
    rotationAnimation.delegate = self;

    // Get the layer
    CALayer* lr = [self layer];

    // Add perspective
    CATransform3D mt = CATransform3DIdentity;
    mt.m34 = 1.0/-1000;
    lr.transform = mt;

    // Set z position so the layer will be on top
    lr.zPosition = 999;

    // Keep cards tilted when flipping
    if(self.tiltCard)
        self.frameCenterRotation = self.frameCenterRotation;

    // Do rotation
    [lr addAnimation:rotationAnimation forKey:@"flip"];
}
Run Code Online (Sandbox Code Playgroud)

翻转代码:

- (void)flipAnimationOutwards{
    // Set correct image
    if (self.faceUp){
        [self setImage:self.faceImage];
    }else{
        [self setImage:[NSImage imageNamed:@"Card_Background"]];
    }

    // Animate shadow
    NSShadow *dropShadow = [[NSShadow alloc] init];
    [dropShadow setShadowOffset:NSMakeSize(0, 1)];
    [dropShadow setShadowBlurRadius:0];
    [dropShadow setShadowColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.0]];
    [[self animator] setShadow:dropShadow];

    // Create CAAnimation
    CABasicAnimation* rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    rotationAnimation.fromValue = [NSNumber numberWithFloat: M_PI/2];
    rotationAnimation.toValue = [NSNumber numberWithFloat: 0.0];
    rotationAnimation.duration = 3.1;
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    rotationAnimation.fillMode = kCAFillModeForwards;
    rotationAnimation.removedOnCompletion = YES;
    [rotationAnimation setValue:@"flipAnimationOutwards" forKey:@"flip"];
    rotationAnimation.delegate = self;

    // Get the layer
    CALayer* lr = [self layer];

    // Add perspective
    CATransform3D mt = CATransform3DIdentity;
    mt.m34 = 1.0/1000;
    lr.transform = mt;

    // Set z position so the layer will be on top
    lr.zPosition = 999;

    // Keep cards tilted when flipping
    if(self.tiltCard)
        self.frameCenterRotation = self.frameCenterRotation;

    // Commit animation
    [lr addAnimation:rotationAnimation forKey:@"flip"];
}
Run Code Online (Sandbox Code Playgroud)

问题:

翻转部分看起来很好.卡的右侧比左侧更高/拉伸,就像它应该的那样.

尽管如此,翻转并不完美.这里右侧较小/拉伸,当它应该是较高/拉伸的左侧.

如何在翻转时使左侧更高/拉伸,而不是使右侧更小/拉伸?

Dav*_*ist 5

你问:

如何在翻转时使左侧更高/拉伸,而不是使右侧更小/拉伸?

你也说翻转工作正常,但翻转是错误的.

两者之间的区别在于透视的标志:

翻转代码:

CATransform3D mt = CATransform3DIdentity;
mt.m34 = 1.0/1000; // note the lack of a minus sign
lr.transform = mt;
Run Code Online (Sandbox Code Playgroud)

翻转代码:

CATransform3D mt = CATransform3DIdentity;
mt.m34 = 1.0/-1000; // note the minus sign
lr.transform = mt;
Run Code Online (Sandbox Code Playgroud)

如果你希望两者看起来一样,那么它们应该具有相同的视角.


根据我的经验,您通常需要负视角值(正如您在示例中的翻转中所做的那样).这与这个值代表"眼睛"/"相机"/"观察者"的位置或任何你称之为的事实有关.

如果你想象一个眼睛位置为(e x,e y,e z)的3D场景,那么变换的透视部分是:

透视变换

假设你正在看世界(即不从侧面看)它的位置将是(0,0,e z)这就是为什么我们通常只m34在添加时设置(第3列,第4行)对变革的看法.

您还可以在Core Animation Programming Guide中看到它的使用方式:

清单5-8向父层添加透视变换

CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0/eyePosition;
Run Code Online (Sandbox Code Playgroud)

如果旋转看起来不对,你应该向另一个方向旋转(例如将旋转从0变为π到从0到-π的旋转或反过来:将旋转从π变为0变为旋转 - π到0.