你如何CAKeyframeAnimation规模? [英] How Do You CAKeyframeAnimation Scale?
问题描述
我想创建一个包含几个关键帧的动画。我希望我的Layer(在这种情况下是一个按钮)
可以扩展到1.5然后降低到0.5然后降到1.2然后降低到0.8然后是1.0。
I want to create an animation with several key frames. I want my Layer (a button in this case) to scale up to 1.5 then down to 0.5 then up to 1.2 then down to 0.8 then 1.0.
我还想要每个关键帧的EaseIn和EaseOut。
I also want to EaseIn and EaseOut of each keyframe.
你可以想象,这将在现场产生一个Springy / Bounce效果。
As you can imagine, this will create a Springy/Bounce effect on the spot.
在我的应用程序的其他部分,我一直在使用CAKeyframeAnimation(见下面的代码)。
这会创建一个类似的弹性动画,但是对于x和y位置。
In other parts of my app I have been using CAKeyframeAnimation like this (see below code). This creates a similar springy animation but for x and y position.
我可以调整以下代码来影响比例而不是位置吗?
提前谢谢!
- (CAAnimation*)monInAnimation {
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path,NULL,113,320);
CGPathAddLineToPoint(path, NULL, 113.5, 283);
CGPathAddLineToPoint(path, NULL, 113.5, 179);
CGPathAddLineToPoint(path, NULL, 113.5, 207);
CGPathAddLineToPoint(path, NULL, 113.5, 187);
CGPathAddLineToPoint(path, NULL, 113.5, 199);
CGPathAddLineToPoint(path, NULL, 113.5, 193);
CGPathAddLineToPoint(path, NULL, 113.5, 195);
CGPathAddLineToPoint(path, NULL, 113.5, 194);
CAKeyframeAnimation *
animation = [CAKeyframeAnimation
animationWithKeyPath:@"position"];
[animation setPath:path];
[animation setDuration:1.5];
[animation setCalculationMode:kCAAnimationLinear];
NSArray *arr = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:0.12],
[NSNumber numberWithFloat:0.24],
[NSNumber numberWithFloat:0.36],
[NSNumber numberWithFloat:0.48],
[NSNumber numberWithFloat:0.60],
[NSNumber numberWithFloat:0.72],
[NSNumber numberWithFloat:0.84],
[NSNumber numberWithFloat:1.0],nil];
[animation setKeyTimes:arr];
[animation setTimingFunctions:[NSArray arrayWithObjects:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], nil]];
//[animation setAutoreverses:YES];
CFRelease(path);
return animation;
}
- (void)monBtnIn {
[monButton.layer setPosition:CGPointMake(113.5,194)];
[monButton.layer addAnimation:[self monInAnimation]
forKey:@"position"];
}
推荐答案
两种替代解决方案:
首先,您还可以为转换属性设置动画。
First, You can also animate the transform property.
使用Brad的代码,但使用@transform作为keypath。主要优点是您不必计算实际帧,而是提供简单的缩放因子:
Using Brad's code, but using @"transform" for the keypath. The primary advantage being that you do not have to calculate the actual frame, but instead provide a simple scaling factor:
Objective-C :
CAKeyframeAnimation *boundsOvershootAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
CATransform3D startingScale = CATransform3DScale (layer.transform, 0, 0, 0);
CATransform3D overshootScale = CATransform3DScale (layer.transform, 1.2, 1.2, 1.0);
CATransform3D undershootScale = CATransform3DScale (layer.transform, 0.9, 0.9, 1.0);
CATransform3D endingScale = layer.transform;
NSArray *boundsValues = [NSArray arrayWithObjects:[NSValue valueWithCATransform3D:startingScale],
[NSValue valueWithCATransform3D:overshootScale],
[NSValue valueWithCATransform3D:undershootScale],
[NSValue valueWithCATransform3D:endingScale], nil];
[boundsOvershootAnimation setValues:boundsValues];
NSArray *times = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:0.5f],
[NSNumber numberWithFloat:0.9f],
[NSNumber numberWithFloat:1.0f], nil];
[boundsOvershootAnimation setKeyTimes:times];
NSArray *timingFunctions = [NSArray arrayWithObjects:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
nil];
[boundsOvershootAnimation setTimingFunctions:timingFunctions];
boundsOvershootAnimation.fillMode = kCAFillModeForwards;
boundsOvershootAnimation.removedOnCompletion = NO;
Swift 4 :
let boundsOvershootAnimation = CAKeyframeAnimation(keyPath: "transform")
let startingScale = CATransform3DScale(layer.transform, 0, 0, 0)
let overshootScale = CATransform3DScale(layer.transform, 1.2, 1.2, 1.0)
let undershootScale = CATransform3DScale(layer.transform, 0.9, 0.9, 1.0)
let endingScale = layer.transform
boundsOvershootAnimation.values = [startingScale, overshootScale, undershootScale, endingScale]
boundsOvershootAnimation.keyTimes = [0.0, 0.5, 0.9, 1.0].map { NSNumber(value: $0) }
boundsOvershootAnimation.timingFunctions = [
CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseOut),
CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut),
CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)
]
boundsOvershootAnimation.fillMode = kCAFillModeForwards
boundsOvershootAnimation.isRemovedOnCompletion = false
其次,可能更容易使用FTUtils,一个核心的开源包装器动画。它包括一个股票弹性动画。
Second, and likely easier, is using FTUtils, an open source wrapper for core animation. It includes a stock "springy" animation.
你可以得到它:
http://github.com/neror/ftutils
这篇关于你如何CAKeyframeAnimation规模?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!