INTUAnimationEngine 1.4.2

INTUAnimationEngine 1.4.2

测试已测试
Lang语言 Obj-CObjective C
许可 MIT
发布最新发布2015年11月

Kristina ThaiTyler FoxJason Hall 维护。



  • 作者
  • Tyler Fox

INTUAnimationEngine

INTUAnimationEngine 使在 iOS 上构建高级自定义动画变得简单。

INTUAnimationEngine 提供了一个友好的接口,使用 CADisplayLink 来驱动自定义动画,灵感来源于 UIView 块动画 API。它能够自动执行为指定持续时间设计的交互式动画(通常由用户输入驱动,例如平移或捏合手势)。它还可以用于获取动画每一帧的回调。

INTUAnimationEngine 包含了一个广泛的缓动函数库,可用于自定义动画时间,以及一个完整的插值函数库,可以动画任何类型的值或属性,包括那些无法通过 Core Animation 动画的。

项目还包括一个独立的应用物理引擎库,用于模拟阻尼谐振运动。这用于底层的 Spring Animation API,该 API 允许完全控制阻尼、刚性和质量参数。由于弹簧求解器是一个完全独立且通用的纯 C 实现的库,它可以被用于动画之外的其他许多应用。

安装

INTUAnimationEngine 需要 iOS 5.0 或更高版本。

仅安装弹簧求解器库

INTUAnimationEngine 使用的弹簧求解器可作为独立的 C 库提供,可将其用于其他应用(包括与动画无关的应用)。Spring Solver 有自己的 CocoaPods 子规范,因此它可以独立于 INTUAnimationEngine 项目的其余部分进行安装。要仅安装弹簧求解器,将以下行添加到您的 Podfile 中

pod 'INTUAnimationEngine/SpringSolver'

请注意,使用 pod 'INTUAnimationEngine' 安装 INTUAnimationEngine 自动包括了弹簧求解器库作为依赖项。

从 GitHub 手动安装

  1. 下载 INTUAnimationEngine 目录 的内容。
  2. 将所有文件添加到您的 Xcode 项目中(拖放最简单)。
  3. 导入 INTUAnimationEngine.h 头文件。

使用方法

INTUAnimationEngine 与 UIView 动画方法的区别主要在于 animations 块的工作方式。在使用 UIView 方法时,animations 块仅执行一次,而这个块中修改的视图表示动画结束时的新状态。

使用INTUAnimationEngine,在动画过程中(每帧一次)会多次执行animations块。每次执行时,您应该在块内根据传递到块的当前percentageprogress值更新视图的状态。通常,您会希望使用此库中包含的其中一个插值函数来帮助生成给定属性起始状态和结束状态之间的所有中间值。

动画引擎

在INTUAnimationEngine上有一组不同的API方法可以用来开始动画。

无缓动(线性)

+ (INTUAnimationID)animateWithDuration:(NSTimeInterval)duration
                                 delay:(NSTimeInterval)delay
                            animations:(void (^)(CGFloat percentage))animations
                            completion:(void (^)(BOOL finished))completion;

此方法将启动一个动画,该动画将在动画的每一帧调用animations块,传递一个表示动画完成百分比的percentage值。当动画完成时,将执行completion块,其中finished参数指示动画是否被取消。

带有缓动

+ (INTUAnimationID)animateWithDuration:(NSTimeInterval)duration
                                 delay:(NSTimeInterval)delay
                                easing:(INTUEasingFunction)easingFunction
                            animations:(void (^)(CGFloat progress))animations
                            completion:(void (^)(BOOL finished))completion;

此方法将启动一个动画,该动画在每一帧动画中调用animations块,传递一个表示动画当前进度的progress值(考虑缓动函数)。easingFunction可以是INTUEasingFunctions.h中的任何缓动函数,或者是一个定义自定义缓动曲线的块。当动画完成时,将执行completion块,其中finished参数指示动画是否被取消。

此外,还有上述方法的另一个变体,它接受一个options:参数,这是一个INTUAnimationOptions的掩码。这可以用来重复或自动反转动画。

使用弹簧

+ (INTUAnimationID)animateWithDamping:(CGFloat)damping
                            stiffness:(CGFloat)stiffness
                                 mass:(CGFloat)mass
                                delay:(NSTimeInterval)delay
                           animations:(void (^)(CGFloat progress))animations
                           completion:(void (^)(BOOL finished))completion;

此方法将启动一个弹簧动画,该动画在每一帧动画中调用animations块,传递一个表示动画当前进度的progress值。动画将模拟具有指定属性的弹簧-质量系统的物理特性:

  • damping – 摩擦量。必须大于或等于零。如果正好为零,谐波运动将无限期地继续。典型范围:1.030.0
  • stiffness – 弹簧的刚度。必须大于零。典型范围:1.0500.0
  • mass – 弹簧移动的质量量。必须大于零。典型范围:0.110.0

请注意,动画的总持续时间是通过模拟具有上述参数的弹簧-质量系统直到达到平衡状态来确定的。当动画完成时,将执行completion块,其中finished参数指示动画是否被取消。

取消动画

+ (void)cancelAnimationWithID:(INTUAnimationID)animationID;

开始动画时,您可以存储返回的动画ID,并将其传递给上述方法来在动画完成之前取消动画。如果动画被取消,则执行完成块,其中finished参数等于NO。

缓动函数

INTUEasingFunctions.h是一个标准缓动函数库。这是一个包含可视化动画演示的有用的速查表

插值函数

INTUInterpolationFunctions.h 是一个插值函数库。

邻近插值

对于离散值(在线性插值不适用的情况下),有两种邻近插值函数。例如

INTUInterpolateDiscrete(NSTextAlignmentLeft, NSTextAlignmentRight, progress)
// Returns NSTextAlignmentLeft when progress is < 0.5, NSTextAlignmentRight otherwise

[INTUInterpolateDiscreteValues(@[@(NSTextAlignmentLeft), @(NSTextAlignmentCenter), @(NSTextAlignmentRight)], progress) integerValue]
// Returns NSTextAlignmentLeft, then NSTextAlignmentCenter, and finally NSTextAlignmentRight as progress increases from 0.0 to 1.0

线性插值

对于连续值,存在多种线性插值函数。以下类型被支持

  • CGFloat
  • CGPoint
  • CGSize
  • CGRect
  • CGVector
  • UIOffset
  • UIEdgeInsets
  • UIColor / CGColor

还有一个无类型的函数 INTUInterpolate(),它接收类型为 id 的值,并自动确定值的类型,返回一个插值值。如果值类型不匹配,或者不支持其类型的线性插值,则使用邻近插值。

CGAffineTransform & CATransform3D

没有直接对变换进行插值的功能。这是有意设计的:原始矩阵的线性插值常常会得到意料之外或无效的结果。要在两个变换之间进行插值,可以将它们分解为其平移、旋转和缩放组件

CGFloat rotation = INTUInterpolateCGFloat(0.0, M_PI, progress);
view.transform = CGAffineTransformMakeRotation(rotation);
// view will rotate from upright (progress = 0.0) to upside down (progress = 1.0)

您可以将变换连接起来以组合它们

CGFloat rotation = INTUInterpolateCGFloat(0.0, M_PI, progress);
CGFloat scale = INTUInterpolateCGFloat(1.0, 0.5, progress);
view.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(scale, scale), CGAffineTransformMakeRotation(rotation));
// view will rotate from upright and full size (progress = 0.0), to upside down and half size (progress = 1.0)
UIColor / CGColor

在两个颜色之间进行插值时,两种颜色必须位于同一颜色空间(灰度、RGB 或 HSB)。在 HSB 颜色空间中插值颜色通常会得到比 RGB 颜色空间更好的视觉效果。

[UIColor colorWithWhite:1.0 alpha:1.0] // Grayscale color space; white
[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0] // RGB color space; white
[UIColor colorWithHue:0.0 saturation:0.0 brightness:1.0 alpha:1.0] // HSB color space; white

弹簧求解器

项目中的 SpringSolver 目录 包含一个弹簧物理库,以模拟阻尼谐振运动,基于为 Facebook 的 Pop 提供动力的弹簧求解器。INTUAnimationEngine 弹簧求解器经过了大量的重构以简化流程和提高性能,作为一个完全独立的纯 C 库,它可以在任何平台上高度移植,并可被用于动画之外的其它用例。

示例项目

提供了一个示例项目。它需要 Xcode 6 和 iOS 6.0 或更高版本。

问题 & 贡献

如果您有问题、建议或其它评论,请在这里打开 GitHub 上的问题

欢迎和鼓励提交合并请求!虽然没有官方指导,但请尽量保持与现有代码风格的统一。

许可证

INTUAnimationEngine 在MIT 许可证下提供。项目中的弹簧求解器库在BSD 许可证下提供。

INTU 在 GitHub 上

查看 Intuit 提供的更多iOS 和 OS X 开源项目!