2021-10-12 15:07:00 +04:00

139 lines
5.4 KiB
Swift

import Foundation
import UIKit
func initializeCompositionLayers(
layers: [LayerModel],
assetLibrary: AssetLibrary?,
frameRate: CGFloat
) -> [MyCompositionLayer] {
var compositionLayers = [MyCompositionLayer]()
var layerMap = [Int : MyCompositionLayer]()
/// Organize the assets into a dictionary of [ID : ImageAsset]
var childLayers = [LayerModel]()
for layer in layers {
if layer.hidden == true {
let genericLayer = MyNullCompositionLayer(layer: layer)
compositionLayers.append(genericLayer)
layerMap[layer.index] = genericLayer
} else if let shapeLayer = layer as? ShapeLayerModel {
let shapeContainer = MyShapeCompositionLayer(shapeLayer: shapeLayer)
compositionLayers.append(shapeContainer)
layerMap[layer.index] = shapeContainer
} else if let solidLayer = layer as? SolidLayerModel {
let solidContainer = MySolidCompositionLayer(solid: solidLayer)
compositionLayers.append(solidContainer)
layerMap[layer.index] = solidContainer
} else if let precompLayer = layer as? PreCompLayerModel,
let assetLibrary = assetLibrary,
let precompAsset = assetLibrary.precompAssets[precompLayer.referenceID] {
let precompContainer = MyPreCompositionLayer(precomp: precompLayer,
asset: precompAsset,
assetLibrary: assetLibrary,
frameRate: frameRate)
compositionLayers.append(precompContainer)
layerMap[layer.index] = precompContainer
} else if let imageLayer = layer as? ImageLayerModel,
let assetLibrary = assetLibrary,
let imageAsset = assetLibrary.imageAssets[imageLayer.referenceID] {
let imageContainer = MyImageCompositionLayer(imageLayer: imageLayer, size: CGSize(width: imageAsset.width, height: imageAsset.height))
compositionLayers.append(imageContainer)
layerMap[layer.index] = imageContainer
} else if let _ = layer as? TextLayerModel {
let genericLayer = MyNullCompositionLayer(layer: layer)
compositionLayers.append(genericLayer)
layerMap[layer.index] = genericLayer
/*let textContainer = TextCompositionLayer(textLayer: textLayer, textProvider: textProvider, fontProvider: fontProvider)
compositionLayers.append(textContainer)
layerMap[layer.index] = textContainer*/
} else {
let genericLayer = MyNullCompositionLayer(layer: layer)
compositionLayers.append(genericLayer)
layerMap[layer.index] = genericLayer
}
if layer.parent != nil {
childLayers.append(layer)
}
}
/// Now link children with their parents
for layerModel in childLayers {
if let parentID = layerModel.parent {
let childLayer = layerMap[layerModel.index]
let parentLayer = layerMap[parentID]
childLayer?.transformNode.parentNode = parentLayer?.transformNode
}
}
return compositionLayers
}
final class MyAnimationContainer {
let bounds: CGRect
var currentFrame: CGFloat = 0.0
/// Forces the view to update its drawing.
func forceDisplayUpdate() {
animationLayers.forEach( { $0.displayWithFrame(frame: currentFrame, forceUpdates: true) })
}
var animationLayers: [MyCompositionLayer]
init(animation: Animation) {
self.animationLayers = []
self.bounds = CGRect(origin: CGPoint(), size: CGSize(width: animation.width, height: animation.height))
let layers = initializeCompositionLayers(layers: animation.layers, assetLibrary: animation.assetLibrary, frameRate: CGFloat(animation.framerate))
var imageLayers = [MyImageCompositionLayer]()
var mattedLayer: MyCompositionLayer? = nil
for layer in layers.reversed() {
layer.bounds = bounds
animationLayers.append(layer)
if let imageLayer = layer as? MyImageCompositionLayer {
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
}
//NOTE
//addSublayer(layer)
}
}
func setFrame(frame: CGFloat) {
self.currentFrame = frame
for animationLayer in self.animationLayers {
animationLayer.displayWithFrame(frame: frame, forceUpdates: false)
}
}
func captureGeometry() -> CapturedGeometryNode {
var subnodes: [CapturedGeometryNode] = []
for animationLayer in self.animationLayers {
let capturedSubnode = animationLayer.captureGeometry()
subnodes.append(capturedSubnode)
}
return CapturedGeometryNode(
transform: CATransform3DIdentity,
alpha: 1.0,
isHidden: false,
displayItem: nil,
subnodes: subnodes
)
}
}