1
1
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:
Victor Sukochev 2016-08-18 15:53:33 +06:00
parent c62e7f91a6
commit 5070c2e1b1
10 changed files with 48 additions and 28 deletions

View File

@ -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:

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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)

View File

@ -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 {

View File

@ -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()
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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)
}
}