mirror of
https://github.com/exyte/Macaw.git
synced 2024-09-17 16:07:44 +03:00
Animation cache refactored not to be singleton
This commit is contained in:
parent
c62e7f91a6
commit
5070c2e1b1
@ -1,11 +1,13 @@
|
||||
import Swift_CAAnimation_Closure
|
||||
|
||||
public class AnimationProducer {
|
||||
class AnimationProducer {
|
||||
|
||||
let sceneLayer: CALayer
|
||||
let animationCache: AnimationCache
|
||||
|
||||
public required init(layer: CALayer) {
|
||||
sceneLayer = layer
|
||||
required init(layer: CALayer, animationCache: AnimationCache) {
|
||||
self.sceneLayer = layer
|
||||
self.animationCache = animationCache
|
||||
animationCache.sceneLayer = layer
|
||||
}
|
||||
|
||||
@ -15,10 +17,10 @@ public class AnimationProducer {
|
||||
case .Unknown:
|
||||
return
|
||||
case .AffineTransformation:
|
||||
addTransformAnimation(animation, sceneLayer: sceneLayer)
|
||||
addTransformAnimation(animation, sceneLayer: sceneLayer, animationCache: animationCache)
|
||||
|
||||
case .Opacity:
|
||||
addOpacityAnimation(animation, sceneLayer: sceneLayer)
|
||||
addOpacityAnimation(animation, sceneLayer: sceneLayer, animationCache: animationCache)
|
||||
case .Sequence:
|
||||
addAnimationSequence(animation)
|
||||
case .Combine:
|
||||
|
@ -2,7 +2,6 @@
|
||||
import UIKit
|
||||
import Macaw
|
||||
|
||||
let animationCache = AnimationCache()
|
||||
class AnimationCache {
|
||||
|
||||
class CachedLayer {
|
||||
@ -20,6 +19,7 @@ class AnimationCache {
|
||||
func layerForNode(node: Node) -> ShapeLayer {
|
||||
guard let cachedLayer = layerCache[node] else {
|
||||
let layer = ShapeLayer()
|
||||
layer.animationCache = self
|
||||
|
||||
// layer.backgroundColor = UIColor.greenColor().CGColor
|
||||
// layer.borderWidth = 1.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
func addOpacityAnimation(animation: Animatable, sceneLayer: CALayer) {
|
||||
func addOpacityAnimation(animation: Animatable, sceneLayer: CALayer, animationCache: AnimationCache) {
|
||||
guard let opacityAnimation = animation as? OpacityAnimation else {
|
||||
return
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import UIKit
|
||||
|
||||
func addTransformAnimation(animation: Animatable, sceneLayer: CALayer) {
|
||||
func addTransformAnimation(animation: Animatable, sceneLayer: CALayer, animationCache: AnimationCache) {
|
||||
guard let transformAnimation = animation as? TransformAnimation else {
|
||||
return
|
||||
}
|
||||
|
@ -8,12 +8,16 @@ class GroupRenderer: NodeRenderer {
|
||||
get { return group }
|
||||
}
|
||||
|
||||
var animationCache: AnimationCache
|
||||
|
||||
let group: Group
|
||||
let disposeBag = DisposeBag()
|
||||
|
||||
init(group: Group, ctx: RenderContext) {
|
||||
init(group: Group, ctx: RenderContext, animationCache: AnimationCache) {
|
||||
self.group = group
|
||||
self.ctx = ctx
|
||||
self.animationCache = animationCache
|
||||
|
||||
hook()
|
||||
}
|
||||
|
||||
@ -39,12 +43,12 @@ class GroupRenderer: NodeRenderer {
|
||||
|
||||
let staticContents = group.contentsVar.filter { !animationCache.isAnimating($0) }
|
||||
|
||||
let contentRenderers = staticContents.map { RenderUtils.createNodeRenderer($0, context: ctx) }
|
||||
let contentRenderers = staticContents.map { RenderUtils.createNodeRenderer($0, context: ctx, animationCache: animationCache) }
|
||||
|
||||
contentRenderers.forEach { renderer in
|
||||
CGContextSaveGState(ctx.cgContext)
|
||||
CGContextConcatCTM(ctx.cgContext, RenderUtils.mapTransform(renderer.node.pos))
|
||||
setClip(renderer.node)
|
||||
CGContextSaveGState(ctx.cgContext)
|
||||
CGContextConcatCTM(ctx.cgContext, RenderUtils.mapTransform(renderer.node.pos))
|
||||
setClip(renderer.node)
|
||||
renderer.render(force, opacity: renderer.node.opacity * opacity)
|
||||
CGContextRestoreGState(ctx.cgContext)
|
||||
}
|
||||
@ -54,10 +58,10 @@ class GroupRenderer: NodeRenderer {
|
||||
var touchedShapes = [Shape]()
|
||||
let staticContents = group.contentsVar.filter { !animationCache.isAnimating($0) }
|
||||
|
||||
let contentRenderers = staticContents.map { RenderUtils.createNodeRenderer($0, context: ctx) }
|
||||
let contentRenderers = staticContents.map { RenderUtils.createNodeRenderer($0, context: ctx, animationCache: animationCache) }
|
||||
|
||||
contentRenderers.forEach { renderer in
|
||||
CGContextSaveGState(ctx.cgContext)
|
||||
CGContextSaveGState(ctx.cgContext)
|
||||
CGContextConcatCTM(ctx.cgContext, RenderUtils.mapTransform(renderer.node.pos))
|
||||
let translatedLocation = CGPointApplyAffineTransform(location, RenderUtils.mapTransform(renderer.node.pos.invert()))
|
||||
setClip(renderer.node)
|
||||
|
@ -39,17 +39,17 @@ class RenderUtils {
|
||||
return p
|
||||
}
|
||||
|
||||
class func createNodeRenderer(node: Node, context: RenderContext) -> NodeRenderer {
|
||||
class func createNodeRenderer(node: Node, context: RenderContext, animationCache: AnimationCache) -> NodeRenderer {
|
||||
if let group = node as? Group {
|
||||
return GroupRenderer(group: group, ctx: context)
|
||||
return GroupRenderer(group: group, ctx: context, animationCache: animationCache)
|
||||
} else if let shape = node as? Shape {
|
||||
return ShapeRenderer(shape: shape, ctx: context)
|
||||
return ShapeRenderer(shape: shape, ctx: context, animationCache: animationCache)
|
||||
} else if let text = node as? Text {
|
||||
return TextRenderer(text: text, ctx: context)
|
||||
return TextRenderer(text: text, ctx: context, animationCache: animationCache)
|
||||
} else if let image = node as? Image {
|
||||
return ImageRenderer(image: image, ctx: context)
|
||||
}
|
||||
fatalError("Unsupported node: \(node)");
|
||||
fatalError("Unsupported node: \(node)");
|
||||
}
|
||||
|
||||
class func applyOpacity(color: Color, opacity: Double) -> Color {
|
||||
|
@ -9,9 +9,13 @@ class ShapeRenderer: NodeRenderer {
|
||||
}
|
||||
let shape: Shape
|
||||
|
||||
init(shape: Shape, ctx: RenderContext) {
|
||||
let animationCache: AnimationCache
|
||||
|
||||
init(shape: Shape, ctx: RenderContext, animationCache: AnimationCache) {
|
||||
self.shape = shape
|
||||
self.ctx = ctx
|
||||
self.animationCache = animationCache
|
||||
|
||||
hook()
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,12 @@ class TextRenderer: NodeRenderer {
|
||||
get { return text }
|
||||
}
|
||||
|
||||
init(text: Text, ctx: RenderContext) {
|
||||
let animationCache: AnimationCache
|
||||
|
||||
init(text: Text, ctx: RenderContext, animationCache: AnimationCache) {
|
||||
self.text = text
|
||||
self.ctx = ctx
|
||||
self.animationCache = animationCache
|
||||
}
|
||||
|
||||
func render(force: Bool, opacity: Double) {
|
||||
|
@ -7,10 +7,10 @@ import UIKit
|
||||
///
|
||||
public class MacawView: UIView {
|
||||
|
||||
/// Scene root node
|
||||
/// Scene root node
|
||||
public var node: Node = Group() {
|
||||
didSet {
|
||||
self.renderer = RenderUtils.createNodeRenderer(node, context: context)
|
||||
self.renderer = RenderUtils.createNodeRenderer(node, context: context, animationCache: animationCache)
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,14 +23,16 @@ public class MacawView: UIView {
|
||||
|
||||
var toRender = true
|
||||
|
||||
private let animationCache = AnimationCache()
|
||||
|
||||
public init?(node: Node, coder aDecoder: NSCoder) {
|
||||
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
self.context = RenderContext(view: self)
|
||||
self.node = node
|
||||
self.animationProducer = AnimationProducer(layer: self.layer)
|
||||
self.renderer = RenderUtils.createNodeRenderer(node, context: context)
|
||||
self.animationProducer = AnimationProducer(layer: self.layer, animationCache: animationCache)
|
||||
self.renderer = RenderUtils.createNodeRenderer(node, context: context, animationCache: animationCache)
|
||||
|
||||
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(MacawView.handlePan))
|
||||
let rotationRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(MacawView.handleRotation))
|
||||
@ -46,7 +48,7 @@ public class MacawView: UIView {
|
||||
|
||||
override public func drawRect(rect: CGRect) {
|
||||
self.context.cgContext = UIGraphicsGetCurrentContext()
|
||||
renderer?.render(false, opacity: node.opacity)
|
||||
renderer?.render(false, opacity: node.opacity)
|
||||
}
|
||||
|
||||
public func addAnimation(animation: Animatable, autoPlay: Bool = true) {
|
||||
|
@ -3,12 +3,17 @@ import UIKit
|
||||
class ShapeLayer: CAShapeLayer {
|
||||
var node: Node?
|
||||
var renderTransform: CGAffineTransform?
|
||||
var animationCache: AnimationCache?
|
||||
|
||||
override func drawInContext(ctx: CGContext) {
|
||||
guard let node = node else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let animationCache = animationCache else {
|
||||
return
|
||||
}
|
||||
|
||||
let renderContext = RenderContext(view: .None)
|
||||
renderContext.cgContext = ctx
|
||||
|
||||
@ -16,7 +21,7 @@ class ShapeLayer: CAShapeLayer {
|
||||
CGContextConcatCTM(ctx, renderTransform)
|
||||
}
|
||||
|
||||
let renderer = RenderUtils.createNodeRenderer(node, context: renderContext)
|
||||
let renderer = RenderUtils.createNodeRenderer(node, context: renderContext, animationCache: animationCache)
|
||||
renderer.render(true, opacity: 1.0)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user