100 lines
2.3 KiB
Swift
100 lines
2.3 KiB
Swift
//
|
|
// RenderLayer.swift
|
|
// lottie-swift
|
|
//
|
|
// Created by Brandon Withrow on 1/18/19.
|
|
//
|
|
|
|
import Foundation
|
|
import QuartzCore
|
|
|
|
/// The layer responsible for rendering shape objects
|
|
final class ShapeRenderLayer: ShapeContainerLayer {
|
|
|
|
// MARK: Lifecycle
|
|
|
|
init(renderer: Renderable & NodeOutput) {
|
|
self.renderer = renderer
|
|
super.init()
|
|
anchorPoint = .zero
|
|
actions = [
|
|
"position" : NSNull(),
|
|
"bounds" : NSNull(),
|
|
"anchorPoint" : NSNull(),
|
|
"path" : NSNull(),
|
|
"transform" : NSNull(),
|
|
"opacity" : NSNull(),
|
|
"hidden" : NSNull(),
|
|
]
|
|
shapeLayer.actions = [
|
|
"position" : NSNull(),
|
|
"bounds" : NSNull(),
|
|
"anchorPoint" : NSNull(),
|
|
"path" : NSNull(),
|
|
"fillColor" : NSNull(),
|
|
"strokeColor" : NSNull(),
|
|
"lineWidth" : NSNull(),
|
|
"miterLimit" : NSNull(),
|
|
"lineDashPhase" : NSNull(),
|
|
"opacity": NSNull(),
|
|
"hidden" : NSNull(),
|
|
]
|
|
addSublayer(shapeLayer)
|
|
|
|
renderer.setupSublayers(layer: shapeLayer)
|
|
}
|
|
|
|
override init(layer: Any) {
|
|
guard let layer = layer as? ShapeRenderLayer else {
|
|
fatalError("init(layer:) wrong class.")
|
|
}
|
|
renderer = layer.renderer
|
|
super.init(layer: layer)
|
|
}
|
|
|
|
required init?(coder _: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
// MARK: Internal
|
|
|
|
fileprivate(set) var renderer: Renderable & NodeOutput
|
|
|
|
let shapeLayer = CAShapeLayer()
|
|
|
|
override func hasRenderUpdate(forFrame: CGFloat) -> Bool {
|
|
isHidden = !renderer.isEnabled
|
|
guard isHidden == false else { return false }
|
|
return renderer.hasRenderUpdates(forFrame)
|
|
}
|
|
|
|
override func rebuildContents(forFrame _: CGFloat) {
|
|
if renderer.shouldRenderInContext {
|
|
if let newPath = renderer.outputPath {
|
|
bounds = renderer.renderBoundsFor(newPath.boundingBox)
|
|
} else {
|
|
bounds = .zero
|
|
}
|
|
position = bounds.origin
|
|
setNeedsDisplay()
|
|
} else {
|
|
shapeLayer.path = renderer.outputPath
|
|
renderer.updateShapeLayer(layer: shapeLayer)
|
|
}
|
|
}
|
|
|
|
override func draw(in ctx: CGContext) {
|
|
if let path = renderer.outputPath {
|
|
if !path.isEmpty {
|
|
ctx.addPath(path)
|
|
}
|
|
}
|
|
renderer.render(ctx)
|
|
}
|
|
|
|
override func updateRenderScale() {
|
|
super.updateRenderScale()
|
|
shapeLayer.contentsScale = renderScale
|
|
}
|
|
}
|