122 lines
3.4 KiB
Swift
122 lines
3.4 KiB
Swift
//
|
|
// PreCompositionLayer.swift
|
|
// lottie-swift
|
|
//
|
|
// Created by Brandon Withrow on 1/25/19.
|
|
//
|
|
|
|
import Foundation
|
|
import QuartzCore
|
|
|
|
final class PreCompositionLayer: CompositionLayer {
|
|
|
|
// MARK: Lifecycle
|
|
|
|
init(
|
|
precomp: PreCompLayerModel,
|
|
asset: PrecompAsset,
|
|
layerImageProvider: LayerImageProvider,
|
|
textProvider: AnimationTextProvider,
|
|
fontProvider: AnimationFontProvider,
|
|
assetLibrary: AssetLibrary?,
|
|
frameRate: CGFloat)
|
|
{
|
|
animationLayers = []
|
|
if let keyframes = precomp.timeRemapping?.keyframes {
|
|
remappingNode = NodeProperty(provider: KeyframeInterpolator(keyframes: keyframes))
|
|
} else {
|
|
remappingNode = nil
|
|
}
|
|
self.frameRate = frameRate
|
|
super.init(layer: precomp, size: CGSize(width: precomp.width, height: precomp.height))
|
|
bounds = CGRect(origin: .zero, size: CGSize(width: precomp.width, height: precomp.height))
|
|
contentsLayer.masksToBounds = true
|
|
contentsLayer.bounds = bounds
|
|
|
|
let layers = asset.layers.initializeCompositionLayers(
|
|
assetLibrary: assetLibrary,
|
|
layerImageProvider: layerImageProvider,
|
|
textProvider: textProvider,
|
|
fontProvider: fontProvider,
|
|
frameRate: frameRate)
|
|
|
|
var imageLayers = [ImageCompositionLayer]()
|
|
|
|
var mattedLayer: CompositionLayer? = nil
|
|
|
|
for layer in layers.reversed() {
|
|
layer.bounds = bounds
|
|
animationLayers.append(layer)
|
|
if let imageLayer = layer as? ImageCompositionLayer {
|
|
imageLayers.append(imageLayer)
|
|
}
|
|
if let matte = mattedLayer {
|
|
/// The previous layer requires this layer to be its matte
|
|
matte.matteLayer = layer
|
|
mattedLayer = nil
|
|
continue
|
|
}
|
|
if
|
|
let matte = layer.matteType,
|
|
matte == .add || matte == .invert
|
|
{
|
|
/// We have a layer that requires a matte.
|
|
mattedLayer = layer
|
|
}
|
|
contentsLayer.addSublayer(layer)
|
|
}
|
|
|
|
childKeypaths.append(contentsOf: layers)
|
|
|
|
layerImageProvider.addImageLayers(imageLayers)
|
|
}
|
|
|
|
override init(layer: Any) {
|
|
/// Used for creating shadow model layers. Read More here: https://developer.apple.com/documentation/quartzcore/calayer/1410842-init
|
|
guard let layer = layer as? PreCompositionLayer else {
|
|
fatalError("init(layer:) Wrong Layer Class")
|
|
}
|
|
frameRate = layer.frameRate
|
|
remappingNode = nil
|
|
animationLayers = []
|
|
|
|
super.init(layer: layer)
|
|
}
|
|
|
|
required init?(coder _: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
// MARK: Internal
|
|
|
|
let frameRate: CGFloat
|
|
let remappingNode: NodeProperty<Vector1D>?
|
|
|
|
override var keypathProperties: [String: AnyNodeProperty] {
|
|
guard let remappingNode = remappingNode else {
|
|
return super.keypathProperties
|
|
}
|
|
return ["Time Remap" : remappingNode]
|
|
}
|
|
|
|
override func displayContentsWithFrame(frame: CGFloat, forceUpdates: Bool) {
|
|
let localFrame: CGFloat
|
|
if let remappingNode = remappingNode {
|
|
remappingNode.update(frame: frame)
|
|
localFrame = remappingNode.value.cgFloatValue * frameRate
|
|
} else {
|
|
localFrame = (frame - startFrame) / timeStretch
|
|
}
|
|
animationLayers.forEach({ $0.displayWithFrame(frame: localFrame, forceUpdates: forceUpdates) })
|
|
}
|
|
|
|
override func updateRenderScale() {
|
|
super.updateRenderScale()
|
|
animationLayers.forEach({ $0.renderScale = renderScale })
|
|
}
|
|
|
|
// MARK: Fileprivate
|
|
|
|
fileprivate var animationLayers: [CompositionLayer]
|
|
}
|