学习笔记29-lottie-ios架构

552 阅读4分钟

lottie-ios 简介

lottie-ios 是 airbnb 的开源库,它允许开发者在 iOS 应用中使用 Adobe After Effects 制作的矢量动画。这些动画通过 lottie 的 Bodymovin 插件以 JSON 文件格式导出,然后可以在 iOS 应用中以原生的方式呈现,这个过程中无需编写复杂的代码或使用图像序列。

接口设计

展示动画与展示图片的需求比较类似,可以采用类似的设计。以 SDWebImage 为例,展示图片的接口设计如下:

@interface UIImageView (WebCache)
- (void)sd_setImageWithURL:(nullable NSURL *)url;
@end

其中界面是 UIImageView,资源标识是 NSURL。

在 lottie-iOS 中展示动画的接口设计如下:

open class LottieAnimationView: LottieAnimationViewBase {
  public var animation: LottieAnimation? {
    get { lottieAnimationLayer.animation }
    set { lottieAnimationLayer.animation = newValue }
  }
  open func play(completion: LottieCompletionBlock? = nil) {
    lottieAnimationLayer.play(completion: completion)
  }
  open func stop() {
    lottieAnimationLayer.stop()
  }
}

其中界面是 LottieAnimationView,动画资源是 LottieAnimation,动画可以被开始播放 play 和停止播放 stop。

界面 LottieAnimationView

LottieAnimationView 是 lottie-ios 库的一个核心类,它作为承载 lottie 动画的界面,可以加载、显示和控制 lottie 动画。 lottie 动画如果用 UIImageView 作为界面的话,使用起来会更方便。但是如果使用 UIImageView 来展示动画,可能有以下一些问题:

  • 性能:UIImageView 主要用于显示静态图片或简单的帧动画。对于复杂的动画,使用 UIImageView 需要频繁地更新图像。
  • 内存:如果使用 UIImageView 来显示复杂的动画,可能需要加载大量的图片帧,这将占用大量的内存。

渲染图层 LottieAnimationLayer

LottieAnimationLayer 负责渲染 lottie 动画,它是 CALayer 的子类,因此它可以无缝地集成到使用 Core Animation 的现有应用中。LottieAnimationLayer 负责将 lottie 动画文件中的矢量图形、形状、文本和图像渲染到屏幕上。

模型 LottieAnimation

LottieAnimation 代表了加载到内存中的 Lottie 动画,这个类负责管理动画的数据结构,包括动画的图层、形状、变换、关键帧等。LottieAnimation 是对动画 JSON 文件内容的解析结果,它为 LottieAnimationLayer 提供了渲染动画所需的所有信息。

Providers

在 lottie-ios 中,Providers 是一种机制,允许开发者从不同的来源加载动画数据。

  • 动态属性更改:开发者可以通过关键路径动态更改动画的属性,如颜色、大小、位置等,这可以通过 setValueProvider 方法实现,允许在运行时替换动画中的值
  • 本地化和文本替换:可以通过 TextProvider 协议替换动画中的文本内容,这对于实现多语言支持和本地化非常有用
  • 图像支持:开发者可以替换动画中的图像资源,这可以通过为图像图层设置 ImageProvider 来实现
open class LottieAnimationView: LottieAnimationViewBase {
  public init(
    animation: LottieAnimation?,
    imageProvider: AnimationImageProvider? = nil,
    textProvider: AnimationKeypathTextProvider = DefaultTextProvider(),
    fontProvider: AnimationFontProvider = DefaultFontProvider(),
    configuration: LottieConfiguration = .shared,
    logger: LottieLogger = .shared) {
  }
  public func setValueProvider(_ valueProvider: AnyValueProvider, keypath: AnimationKeypath) {
  }
}

高级组件

lottie-ios 除了提供基本的动画渲染功能外,还包含了一些高级组件,用于创建具有动画效果的交互式UI元素。

  • AnimatedButton: 允许你为按钮的不同状态指定 lottie 动画。这样,当用户与按钮交互式,按钮会显示动画效果,从而提供更丰富的用户体验。
/// Set a play range with Progress Time.
public func setPlayRange(fromProgress: AnimationProgressTime, 
    toProgress: AnimationProgressTime, 
    event: UIControl.Event)
/// Set a play range with Marker Keys.
public func setPlayRange(fromMarker fromName: String, 
    toMarker toName: String, 
    event: UIControl.Event)
  • AnimatedSwitch: 它使用 Lottie 动画来代替标准的开关状态指示器。你可以为开关的开启和关闭状态指定不同的 Lottie 动画,从而创建一个具有动画效果的开关控件。
/// Sets the play range for the given state. When the switch is toggled, the animation range is played.
public func setProgressForState(fromProgress: AnimationProgressTime,
    toProgress: AnimationProgressTime,
    forState onState: Bool)

渲染引擎

在 Lottie 4.0 中,AirBnb 放弃了使用 CADisplayLink 在主 CPU 线程上制作图形动画的原始方法,采用了 Core Animation,提供了显著的性能改进,并降低了 CPU 负载。

  • Core Animation 渲染引擎: 使用核心动画 CAAnimations 来提供比旧主线程渲染引擎更好的性能
  • Main Thread 渲染引擎: 每帧在主线程上运行一次代码来更新和重新渲染动画。

架构图

lottie.jpg

参考文档