- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 iOS 中很好地沿着 CGPath
(QuadCurve) 制作 CALayer
动画。但我想使用比少数几个更有趣的缓动函数 provided由苹果公司(EaseIn/EaseOut 等)。例如,弹跳或弹性函数。
这些事情可以用 MediaTimingFunction (bezier) 来做:
但我想创建更复杂的计时函数。问题是媒体定时似乎需要三次贝塞尔曲线,但它的强度不足以产生这些效果:
code在其他框架中创建上述内容非常简单,这使得这非常令人沮丧。请注意,这些曲线是将输入时间映射到输出时间(T-t 曲线),而不是时间-位置曲线。例如,easeOutBounce(T) = t 返回一个新的t。然后,t 用于绘制运动(或我们应该设置动画的任何属性)。
所以,我想创建一个复杂的自定义 CAMediaTimingFunction
但我不知道如何做到这一点,或者是否可能?还有其他选择吗?
编辑:
这是步骤的具体示例。非常有教育意义:)
我想要沿着从点 a 到 b 的直线为对象设置动画,但我希望它使用上面的 escapeOutBounce 曲线。这意味着它将沿着从 a 到 b 的精确路线,但会以比当前基于贝塞尔曲线的 CAMediaTimingFunction 更复杂的方式加速和减速。
让该线成为由 CGPath 指定的任意曲线移动。它仍应沿着该曲线移动,但应以与线条示例中相同的方式加速和减速。
理论上我认为它应该像这样工作:
让我们将运动曲线描述为关键帧动画move(t) = p,其中t是时间[0..1],p em> 是在时间 t 计算的位置。因此,move(0) 返回曲线起点的位置,move(0.5) 返回曲线的中间位置,move(1) 返回曲线末尾的位置。使用计时函数 time(T) = t 为 move 提供 t 值应该可以满足我的需求。对于弹跳效果,计时函数应为 time(0.8) 和 time(0.8) 返回相同的 t 值(仅作为示例) 。只需更换定时函数即可得到不同的效果。
(是的,可以通过创建和连接四个来回的线段来进行线弹跳,但这不是必需的。毕竟,它只是一个映射时间<的简单线性函数/em> 值到位置。)
我希望我说得有道理。
最佳答案
我发现了这个:
Cocoa with Love - Parametric acceleration curves in Core Animation
但我认为通过使用 block 可以使其变得更简单且更具可读性。因此,我们可以在 CAKeyframeAnimation 上定义一个类别,如下所示:
CAKeyframeAnimation+Parametric.h:
// this should be a function that takes a time value between
// 0.0 and 1.0 (where 0.0 is the beginning of the animation
// and 1.0 is the end) and returns a scale factor where 0.0
// would produce the starting value and 1.0 would produce the
// ending value
typedef double (^KeyframeParametricBlock)(double);
@interface CAKeyframeAnimation (Parametric)
+ (id)animationWithKeyPath:(NSString *)path
function:(KeyframeParametricBlock)block
fromValue:(double)fromValue
toValue:(double)toValue;
CAKeyframeAnimation+Parametric.m:
@implementation CAKeyframeAnimation (Parametric)
+ (id)animationWithKeyPath:(NSString *)path
function:(KeyframeParametricBlock)block
fromValue:(double)fromValue
toValue:(double)toValue {
// get a keyframe animation to set up
CAKeyframeAnimation *animation =
[CAKeyframeAnimation animationWithKeyPath:path];
// break the time into steps
// (the more steps, the smoother the animation)
NSUInteger steps = 100;
NSMutableArray *values = [NSMutableArray arrayWithCapacity:steps];
double time = 0.0;
double timeStep = 1.0 / (double)(steps - 1);
for(NSUInteger i = 0; i < steps; i++) {
double value = fromValue + (block(time) * (toValue - fromValue));
[values addObject:[NSNumber numberWithDouble:value]];
time += timeStep;
}
// we want linear animation between keyframes, with equal time steps
animation.calculationMode = kCAAnimationLinear;
// set keyframes and we're done
[animation setValues:values];
return(animation);
}
@end
现在用法将如下所示:
// define a parametric function
KeyframeParametricBlock function = ^double(double time) {
return(1.0 - pow((1.0 - time), 2.0));
};
if (layer) {
[CATransaction begin];
[CATransaction
setValue:[NSNumber numberWithFloat:2.5]
forKey:kCATransactionAnimationDuration];
// make an animation
CAAnimation *drop = [CAKeyframeAnimation
animationWithKeyPath:@"position.y"
function:function fromValue:30.0 toValue:450.0];
// use it
[layer addAnimation:drop forKey:@"position"];
[CATransaction commit];
}
我知道这可能不像您想要的那么简单,但这是一个开始。
关于iphone - 如何使用 Core Animation 创建自定义缓动函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5161465/
我是一名优秀的程序员,十分优秀!