Anima 是一个适用于 iOS、tvOS 和 macOS 的动画框架。 它允许你使用弹簧、缓动和衰减动画来设置属性动画。
请查看包含的示例应用程序,其中演示了大多数功能。
如需完整的文档,请查看 在线文档。
任何符合 AnimatableProperty
协议的类型都可以被 Anima
设置动画。
默认情况下,许多类型已经符合该协议
Float (浮点数)
Double (双精度浮点数)
CGFloat (Core Graphics 浮点数)
CGPoint (点)
CGSize (尺寸)
CGRect (矩形)
CGColor
/NSColor
/UIColor
(颜色)CATransform3D
/ CGAffineTransform
(变换)AnimatableProperty
值的数组有两种创建动画的方式:基于代码块(block-based) 和 基于属性(property-based)。
基于代码块的动画让你能够轻松地设置符合 AnimatablePropertyProvider
协议的对象的属性动画。
许多对象已经符合该协议并提供可动画的属性
NSView
, NSWindow
, NSTextField
, NSImageView
以及更多。UIView
, UILabel
, UIImageView
以及更多。NSLayoutConstraint
和 CALayer
这些属性可以通过对象的 animator
访问。要对它们进行动画处理,请使用 Anima.animate(…)
在动画代码块中更改它们的值。 例如
Anima.animate(withSpring: .bouncy) {
view.animator.frame = newFrame
view.animator.backgroundColor = .systemBlue
textField.animator.fontSize = 20
}
要停止属性的动画并立即更新它,请在动画代码块之外更改其值。 例如
view.animator.backgroundColor = .systemRed
一种基于弹簧的流畅动画。
你提供一个 Spring
,它描述了弹簧的配置。 Spring
提供了许多预定义的配置,如 bouncy
(有弹性的)、smooth
(平滑的)、snappy
(快速的)或 Spring(duration: CGFloat, bouncy: CGFloat)
)。
Anima.animate(withSpring: .bouncy) {
view.animator.frame = newFrame
view.animator.backgroundColor = .systemBlue
}
当更改当前正在动画处理的属性的值时,动画的速度会被保留以提供流畅的动画。这就是为什么弹簧动画是响应式和交互式 UI 的推荐动画。
你可以为弹簧动画提供手势速度。这可以用来将手势识别器(当手势结束时)的速度“注入”到动画中。 如果你应用了 CGPoint
类型的速度,它将用于对 GGPoint
和 CGRect
类型的属性进行动画处理。
let velocity = panGestureRecognizer.velocity(in: view)
Anima.animate(withSpring: .snappy, gestureVelocity: velocity) {
view.animator.frame.origin = CGPoint(x: 200, y: 200)
}
一种基于缓动的动画。
你提供一个 TimingFunction
,它描述了动画的缓动(例如 easeIn
、easeInOut
或 linear
)和持续时间。
Anima.animate(withEasing: .easeIn, duration: 3.0) {
view.animator.frame = newFrame
view.animator.backgroundColor = .systemBlue
}
执行具有衰减加速度的动画。
你要么提供值,动画会将属性以减速的加速度动画处理到这些值。
Anima.animate(withDecay: .value) {
view.animator.frame = newFrame
view.animator.backgroundColor = .systemBlue
}
要么提供速度值。 属性将根据速度值增加或减少,并减速停止。 这本质上提供了与 UIScrollView
在你拖动并释放时相同的“衰减”。 动画以速度作为种子,并且该速度会随着时间的推移而衰减。
Anima.animate(withDecay: .velocity) {
// The origin's y value will increase 200 points. (e.g. if the origin`s y value is 250 it will move to 450)
view.animator.frame.origin.y = 200
}
虽然基于代码块的 API 通常是最方便的,但你可能想要对不提供可动画属性的对象进行动画处理。 或者,你可能想要获得动画的中间值并自己驱动动画的灵活性。
要创建基于属性的动画,你需要提供一个初始值、目标值和 valueChanged
,这是一个每当动画的当前值发生变化时都会调用的代码块。
let value = CGPoint(x: 0, y: 0)
let target = CGPoint(x: 100, y: 100)
let springAnimation = SpringAnimation(spring: .bouncy, value: value, target: target)
springAnimation.valueChanged = { newValue in
view.frame.origin = newValue
}
springAnimation.start()
let easingAnimation = EasingAnimation(timingFunction: .easeIn, duration: 2.0, value: value, target: target)
easingAnimation.valueChanged = { newValue in
view.frame.origin = newValue
}
easingAnimation.start()
// Decay animation with target
let decayAnimation = DecayAnimation(value: value, target: target)
decayAnimation.valueChanged = { newValue in
view.frame.origin = newValue
}
decayAnimation.start()
// Decay animation with velocity
let decayVelocityAnimation = DecayAnimation(value: value, velocity: velocity)
要创建你自己的动画,请重写这个 ValueAnimation
。 该类不会进行动画处理,你必须提供你自己的动画逻辑。
Anima 中的所有动画都符合 CAKeyframeAnimationEmittable
协议,并通过 keyframeAnimation
提供一个镜像动画的 CAKeyframeAnimation
。 持续时间、关键帧和所有其他内容都会自动计算。 唯一的区别是 valueChanged
和 completion
无法使用,并且你必须指定要动画处理的 keypath。
例如
let springAnimation = SpringAnimation<CGRect>(spring: .bouncy, value: frame, target: targetFrame)
let keyframeAnimation = springAnimation.keyframeAnimation()
keyframeAnimation.keyPath = "frame"
layer.add(keyframeAnimation, forKey: "MyAnimation")
注意:如果你删除或中断动画,并且你希望它像所有其他 Core Animation 动画一样保持在屏幕上的位置,你将需要从图层的 presentationLayer
中获取该值并将其应用于图层(以及担心 fillMode
)。
橡皮筋效果是指使值看起来像在橡皮筋上(它们会根据交互拉伸和滑动)。 当你拉过 contentSize 时,UIScrollView
会执行此操作,并且通过使用 Motion 中的橡皮筋函数,你可以为自己重新创建此交互。
bounds.origin.x = rubberband(bounds.origin.x - translation.x, boundsSize: bounds.size.width, contentSize: contentSize.width)
Anima 部分基于 Wave 和 Motion。 它使用 Waves
的弹簧计算和一些动画逻辑以及 Motion
的衰减和缓动计算。
没有这些库,Anima 就不可能实现。
将 Anima 添加到你的应用程序的 Package.swift 文件中,或者在 Xcode 中选择 File -> Add Packages
.package(url: "https://github.com/flocked/Anima")
如果你克隆了 repo,你可以运行示例应用程序,其中包含一些交互式演示来了解 Anima 提供的功能。
注意:要在 ProMotion 设备上启用高帧率动画(即 120 fps 动画),你需要在 Info.plist 中添加一个键/值对。 将键 CADisableMinimumFrameDuration
设置为 `true。 如果没有这个条目,动画将被限制为 60 fps。