Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,32 @@ class AnimationsHierarchyViewController: UIViewController {

@IBOutlet weak var animView: MacawView!

var startCallbacks: [()->()] = []
var stopCallbacks: [()->()] = []

override func viewDidLoad() {
super.viewDidLoad()

animView.node = createTree(height: 3)
animView.zoom.enable()
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

startCallbacks.forEach {
$0()
}
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

stopCallbacks.forEach {
$0()
}
}

func createTree(height: Int) -> Node {
let rect = Rect(w: 10, h: 10)

Expand Down Expand Up @@ -52,7 +71,14 @@ class AnimationsHierarchyViewController: UIViewController {
func createLeaf(childForm: Locus, xDelta: Double, yDelta: Double) -> Group {
let inset = childForm.bounds().w / 2
let leaf = Shape(form: childForm, fill: Color.teal, place: .move(dx: -inset, dy: -inset))
leaf.placeVar.animation(angle: 2 * .pi, during: 5).cycle().play()

let animation = leaf.placeVar.animation(angle: 2 * .pi, during: 5).cycle()
startCallbacks.append({
animation.play()
})
stopCallbacks.append({
animation.stop()
})

let leafGroup = [leaf].group(place: .move(dx: xDelta, dy: yDelta))
leaf.onTap { _ in
Expand Down
11 changes: 6 additions & 5 deletions Source/animation/AnimationImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@ class BasicAnimation: Animation {

weak var node: Node? {
didSet {
node?.animations.append(self)
if let group = node as? Group {
for node in group.contents {
node.animations.append(self)
}
if !(self is CombineAnimation || self is AnimationSequence || self is EmptyAnimation) {
node?.animations.append(self)
}
}
}
Expand Down Expand Up @@ -104,6 +101,8 @@ class BasicAnimation: Animation {
}

removeFunc?()
node?.animations.removeAll { $0 === self }
nodeRenderer?.freeLayer()
}

override open func pause() {
Expand All @@ -115,6 +114,8 @@ class BasicAnimation: Animation {
}

removeFunc?()
node?.animations.removeAll { $0 === self }
nodeRenderer?.freeLayer()
}

override func state() -> AnimationState {
Expand Down
6 changes: 3 additions & 3 deletions Source/animation/AnimationProducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ class AnimationProducer {
}

// MARK: - Sequence animation
func addAnimationSequence(_ animationSequnce: Animation,
func addAnimationSequence(_ animationSequence: Animation,
_ context: AnimationContext) {
guard let sequence = animationSequnce as? AnimationSequence else {
guard let sequence = animationSequence as? AnimationSequence else {
return
}

Expand Down Expand Up @@ -198,7 +198,7 @@ class AnimationProducer {
}

// MARK: - Stored animation
func addStoredAnimations(_ node: Node, _ view: MacawView) {
func addStoredAnimations(_ node: Node, _ view: DrawingView) {
addStoredAnimations(node, AnimationContext())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import AppKit

class AnimationUtils {

class func layerForNodeRenderer(_ renderer: NodeRenderer, _ context: AnimationContext, animation: Animation, customBounds: Rect? = .none, shouldRenderContent: Bool = true) -> ShapeLayer {
class func layerForNodeRenderer(_ renderer: NodeRenderer, animation: Animation, customBounds: Rect? = .none, shouldRenderContent: Bool = true) -> ShapeLayer {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should try to use maximum line length equal to 120 symbols (for example)? Long lines are really uncomfortable to read and understand, especially here on Github.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great to add it to our SwiftLint 😉

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you agree - it takes about 5 mines to update rules for SwiftLint and maybe some time to format current issues.


let node = renderer.node
if let cachedLayer = renderer.layer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ extension AnimationProducer {
// MARK: - Combine animation
func addCombineAnimation(_ combineAnimation: Animation, _ context: AnimationContext) {
guard let combine = combineAnimation as? CombineAnimation,
let renderer = combine.nodeRenderer,
let _ = renderer.view else {
let _ = combine.nodeRenderer,
let node = combine.node else {
return
}

Expand Down Expand Up @@ -176,6 +176,7 @@ extension AnimationProducer {
}

combine.removeFunc = {
node.animations.removeAll { $0 === combine }
animations.forEach { animation in
animation.removeFunc?()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func addMorphingAnimation(_ animation: BasicAnimation, _ context: AnimationConte
let toLocus = morphingAnimation.getVFunc()(animation.autoreverses ? 0.5 : 1.0)
let duration = animation.autoreverses ? animation.getDuration() / 2.0 : animation.getDuration()

let layer = AnimationUtils.layerForNodeRenderer(renderer, context, animation: animation, shouldRenderContent: false)
let layer = AnimationUtils.layerForNodeRenderer(renderer, animation: animation, shouldRenderContent: false)

// Creating proper animation
let generatedAnimation = pathAnimation(
Expand Down Expand Up @@ -94,6 +94,7 @@ func addMorphingAnimation(_ animation: BasicAnimation, _ context: AnimationConte
let animationId = animation.ID
layer.add(generatedAnimation, forKey: animationId)
animation.removeFunc = { [weak layer] in
shape.animations.removeAll { $0 === animation }
layer?.removeAnimation(forKey: animationId)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ func addOpacityAnimation(_ animation: BasicAnimation, _ context: AnimationContex
node.opacityVar.value = opacityAnimation.getVFunc()(1.0)
}

CATransaction.begin()
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
renderer.layer?.animationLayer.opacity = Float(node.opacity)
CATransaction.commit()

if !animation.paused {
animation.removeFunc?()
}

renderer.freeLayer()

if !animation.cycled &&
Expand All @@ -58,10 +67,11 @@ func addOpacityAnimation(_ animation: BasicAnimation, _ context: AnimationContex
completion()
}

let layer = AnimationUtils.layerForNodeRenderer(renderer, context, animation: animation)
let layer = AnimationUtils.layerForNodeRenderer(renderer, animation: animation)
let animationId = animation.ID
layer.add(generatedAnimation, forKey: animationId)
animation.removeFunc = { [weak layer] in
node.animations.removeAll { $0 === animation }
layer?.removeAnimation(forKey: animationId)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func addShapeAnimation(_ animation: BasicAnimation, _ context: AnimationContext,
let toShape = shapeAnimation.getVFunc()(animation.autoreverses ? 0.5 : 1.0)
let duration = animation.autoreverses ? animation.getDuration() / 2.0 : animation.getDuration()

let layer = AnimationUtils.layerForNodeRenderer(renderer, context, animation: animation, shouldRenderContent: false)
let layer = AnimationUtils.layerForNodeRenderer(renderer, animation: animation, shouldRenderContent: false)

// Creating proper animation
let generatedAnimation = generateShapeAnimation(context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func addTransformAnimation(_ animation: BasicAnimation, _ context: AnimationCont
let transactionsDisabled = CATransaction.disableActions()
CATransaction.setDisableActions(true)

let layer = AnimationUtils.layerForNodeRenderer(renderer, context, animation: animation, shouldRenderContent: true)
let layer = AnimationUtils.layerForNodeRenderer(renderer, animation: animation, shouldRenderContent: true)

// Creating proper animation
let generatedAnimation = transformAnimationByFunc(transformAnimation,
Expand Down Expand Up @@ -54,6 +54,15 @@ func addTransformAnimation(_ animation: BasicAnimation, _ context: AnimationCont
node.placeVar.value = transformAnimation.getVFunc()(1.0)
}

CATransaction.begin()
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
renderer.layer?.animationLayer.transform = CATransform3DMakeAffineTransform(node.place.toCG())
CATransaction.commit()

if !animation.paused {
animation.removeFunc?()
}

renderer.freeLayer()

if !animation.cycled &&
Expand All @@ -68,6 +77,7 @@ func addTransformAnimation(_ animation: BasicAnimation, _ context: AnimationCont
let animationId = animation.ID
layer.add(generatedAnimation, forKey: animationId)
animation.removeFunc = { [weak layer] in
node.animations.removeAll { $0 === animation }
layer?.removeAnimation(forKey: animationId)
}

Expand Down
4 changes: 2 additions & 2 deletions Source/export/MacawView+PDF.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public extension MacawView {
y: -size.height / bounds.height
)

context.cgContext = ctx
renderer?.render(in: ctx, force: false, opacity: node.opacity)
drawingView.context.cgContext = ctx
drawingView.renderer?.render(in: ctx, force: false, opacity: node.opacity)

ctx.endPDFPage()
}
Expand Down
2 changes: 1 addition & 1 deletion Source/render/GroupRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class GroupRenderer: NodeRenderer {
return group
}

init(group: Group, view: MacawView?, parentRenderer: GroupRenderer? = nil) {
init(group: Group, view: DrawingView?, parentRenderer: GroupRenderer? = nil) {
self.group = group
super.init(node: group, view: view, parentRenderer: parentRenderer)
updateRenderers()
Expand Down
2 changes: 1 addition & 1 deletion Source/render/ImageRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ImageRenderer: NodeRenderer {
return image
}

init(image: Image, view: MacawView?, parentRenderer: GroupRenderer? = nil) {
init(image: Image, view: DrawingView?, parentRenderer: GroupRenderer? = nil) {
self.image = image
super.init(node: image, view: view, parentRenderer: parentRenderer)
}
Expand Down
4 changes: 2 additions & 2 deletions Source/render/NodeRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CachedLayer {

class NodeRenderer {

weak var view: MacawView?
weak var view: DrawingView?
var sceneLayer: CALayer? {
return view?.mLayer
}
Expand Down Expand Up @@ -71,7 +71,7 @@ class NodeRenderer {
fatalError("Unsupported")
}

init(node: Node, view: MacawView?, parentRenderer: GroupRenderer? = nil) {
init(node: Node, view: DrawingView?, parentRenderer: GroupRenderer? = nil) {
self.view = view
self.parentRenderer = parentRenderer

Expand Down
4 changes: 2 additions & 2 deletions Source/render/RenderContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import UIKit
#endif

class RenderContext {
weak var view: MacawView?
weak var view: DrawingView?
var cgContext: CGContext?

init(view: MacawView?) {
init(view: DrawingView?) {
self.view = view
self.cgContext = nil
}
Expand Down
2 changes: 1 addition & 1 deletion Source/render/RenderUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class RenderUtils {
return p
}

class func createNodeRenderer(_ node: Node, view: MacawView?, parentRenderer: GroupRenderer? = nil) -> NodeRenderer {
class func createNodeRenderer(_ node: Node, view: DrawingView?, parentRenderer: GroupRenderer? = nil) -> NodeRenderer {
if let group = node as? Group {
return GroupRenderer(group: group, view: view, parentRenderer: parentRenderer)
} else if let shape = node as? Shape {
Expand Down
2 changes: 1 addition & 1 deletion Source/render/ShapeRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ShapeRenderer: NodeRenderer {

var shape: Shape

init(shape: Shape, view: MacawView?, parentRenderer: GroupRenderer? = nil) {
init(shape: Shape, view: DrawingView?, parentRenderer: GroupRenderer? = nil) {
self.shape = shape
super.init(node: shape, view: view, parentRenderer: parentRenderer)
}
Expand Down
2 changes: 1 addition & 1 deletion Source/render/TextRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TextRenderer: NodeRenderer {
return text
}

init(text: Text, view: MacawView?, parentRenderer: GroupRenderer? = nil) {
init(text: Text, view: DrawingView?, parentRenderer: GroupRenderer? = nil) {
self.text = text
super.init(node: text, view: view, parentRenderer: parentRenderer)
}
Expand Down
Loading