diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index 5f9d42c2..6962542c 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 24BE07041C6DF1F000B5882F /* BasePageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24BE07031C6DF1F000B5882F /* BasePageViewController.swift */; }; + 5708F7E61CC8A783002AA500 /* PathExampleController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5708F7E51CC8A783002AA500 /* PathExampleController.swift */; }; 574EC4371CB7DE7F0063F317 /* CleanerExampleController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574EC4291CB7DE7F0063F317 /* CleanerExampleController.swift */; }; 574EC4381CB7DE7F0063F317 /* CleanersGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574EC42A1CB7DE7F0063F317 /* CleanersGraphics.swift */; }; 574EC4391CB7DE7F0063F317 /* CleanerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574EC42B1CB7DE7F0063F317 /* CleanerView.swift */; }; @@ -62,6 +63,7 @@ /* Begin PBXFileReference section */ 24BE07031C6DF1F000B5882F /* BasePageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasePageViewController.swift; sourceTree = ""; }; + 5708F7E51CC8A783002AA500 /* PathExampleController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PathExampleController.swift; sourceTree = ""; }; 574EC4291CB7DE7F0063F317 /* CleanerExampleController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CleanerExampleController.swift; sourceTree = ""; }; 574EC42A1CB7DE7F0063F317 /* CleanersGraphics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CleanersGraphics.swift; sourceTree = ""; }; 574EC42B1CB7DE7F0063F317 /* CleanerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CleanerView.swift; sourceTree = ""; }; @@ -149,6 +151,7 @@ isa = PBXGroup; children = ( 574EC4321CB7DE7F0063F317 /* PathExampleView.swift */, + 5708F7E51CC8A783002AA500 /* PathExampleController.swift */, ); path = Path; sourceTree = ""; @@ -311,6 +314,7 @@ 574EC43F1CB7DE7F0063F317 /* TextExampleView.swift in Sources */, 574EC43C1CB7DE7F0063F317 /* RectShapeView.swift in Sources */, 574EC4441CBB60AF0063F317 /* AnimationsExampleController.swift in Sources */, + 5708F7E61CC8A783002AA500 /* PathExampleController.swift in Sources */, 575129B61CBD14AF00BD3C2E /* AnimationsView.swift in Sources */, 24BE07041C6DF1F000B5882F /* BasePageViewController.swift in Sources */, 574EC43A1CB7DE7F0063F317 /* DiagramExampleView.swift in Sources */, diff --git a/Example/Example/Base.lproj/Main.storyboard b/Example/Example/Base.lproj/Main.storyboard index 1f61f994..ac9e1eb8 100644 --- a/Example/Example/Base.lproj/Main.storyboard +++ b/Example/Example/Base.lproj/Main.storyboard @@ -147,7 +147,7 @@ - + @@ -187,6 +187,9 @@ + + + diff --git a/Example/Example/BasePageViewController.swift b/Example/Example/BasePageViewController.swift index ff7824a0..71ac921f 100644 --- a/Example/Example/BasePageViewController.swift +++ b/Example/Example/BasePageViewController.swift @@ -8,7 +8,7 @@ class BasePageViewController: UIPageViewController { self.newMacawViewController("MenuViewController"), self.newMacawViewController("FirstPageViewController"), self.newMacawViewController("SecondPageViewController"), - self.newMacawViewController("ThirdPageViewController"), + self.newMacawViewController("PathExampleController"), self.newMacawViewController("FourthPageViewController"), self.newMacawViewController("AnimationsExampleController"), self.newMacawViewController("ModelListenersExampleController"), diff --git a/Example/Example/Examples/Path/PathExampleController.swift b/Example/Example/Examples/Path/PathExampleController.swift new file mode 100644 index 00000000..3e6d7d91 --- /dev/null +++ b/Example/Example/Examples/Path/PathExampleController.swift @@ -0,0 +1,11 @@ +import UIKit + +class PathExampleController: UIViewController { + @IBOutlet var sceneView: PathExampleView? + + override func viewDidAppear(animated: Bool) { + super.viewDidAppear(animated) + + sceneView?.testAnimation() + } +} diff --git a/Example/Example/Examples/Path/PathExampleView.swift b/Example/Example/Examples/Path/PathExampleView.swift index cf0a4cca..63559535 100644 --- a/Example/Example/Examples/Path/PathExampleView.swift +++ b/Example/Example/Examples/Path/PathExampleView.swift @@ -203,18 +203,47 @@ class PathExampleView: MacawView { super.addAnimation(animation2, autoPlay: false) */ - let n = 100 - let g = 800.0 +// 2 + /* + let n = 100 + let g = 800.0 + var clouds = [Node]() + for _ in 0 ... (n - 1) { + let cloud = cloudExample() + let velocity = Point(x: -700 + Double(rand() % 1400), + y: -700 + Double(rand() % 1400)) + let flying = PathAnimation(observableValue: cloud.posProperty, function: { t in + let x = velocity.x * t + let y = velocity.y * t + g * t * t; + return Transform.move(100.0 + x, my: 100 + y).scale(0.05, sy: 0.05) + }, animationDuration: 10.0) + animation.append(flying) + clouds.append(cloud) + } + + let group = Group( + contents: clouds, + pos: Transform().move(-80, my: -100)) + super.init(node: group, coder: aDecoder) + + animation.forEach { anim in + super.addAnimation(anim, autoPlay: false) + } + + */ + + let n = 200 + // let g = 800.0 var clouds = [Node]() for _ in 0 ... (n - 1) { let cloud = cloudExample() - let velocity = Point(x: -700 + Double(rand() % 1400), + let velocity = Point(x: -1000 + Double(rand() % 2000), y: -700 + Double(rand() % 1400)) - let flying = PathAnimation(observableValue: cloud.posProperty, function: { t in - let x = velocity.x * t - let y = velocity.y * t + g * t * t; - return Transform.move(100.0 + x, my: 100 + y).scale(0.05, sy: 0.05) - }, animationDuration: 10.0) + let flying = TransformAnimation(animatedShape: cloud, + observableValue: cloud.posProperty, + startValue: Transform.move(0.0, my: 0.0).scale(0.3, sy: 0.3), + finalValue: Transform.move(velocity.x, my: velocity.y).scale(0.3, sy: 0.3), + animationDuration: 1.0) animation.append(flying) clouds.append(cloud) } @@ -223,14 +252,16 @@ class PathExampleView: MacawView { contents: clouds, pos: Transform().move(-80, my: -100)) super.init(node: group, coder: aDecoder) - - animation.forEach { anim in - super.addAnimation(anim, autoPlay: false) - } } required init?(node: Node, coder aDecoder: NSCoder) { // animations = [] super.init(node: node, coder: aDecoder) } + + func testAnimation() { + animation.forEach { anim in + super.addAnimation(anim, autoPlay: false) + } + } } diff --git a/Source/animation/Animation.swift b/Source/animation/Animation.swift index 97ff1360..71c71325 100644 --- a/Source/animation/Animation.swift +++ b/Source/animation/Animation.swift @@ -33,7 +33,7 @@ enum AnimationType { public class Animatable { - var shape: Shape? + var shape: Group? var type = AnimationType.Unknown var shouldBeRemoved = false @@ -44,7 +44,7 @@ public class Animatable { public let currentProgress = ObservableValue(value: 0) func animate(progress: Double) { } - func getDuration() -> Double { return 0 } + func getDuration() -> Double { return 0 } func play() { paused = false diff --git a/Source/animation/AnimationProducer.swift b/Source/animation/AnimationProducer.swift index e2b594ac..d5312503 100644 --- a/Source/animation/AnimationProducer.swift +++ b/Source/animation/AnimationProducer.swift @@ -47,37 +47,41 @@ public class AnimationProducer { // layer.setAffineTransform(cgTransformStart) - let scaleX = CABasicAnimation(keyPath: "scale.x") + let scaleX = CABasicAnimation(keyPath: "transform.scale.x") scaleX.fromValue = startScaleX scaleX.toValue = finalScaleX scaleX.duration = animation.getDuration() - let scaleY = CABasicAnimation(keyPath: "scale.y") + let scaleY = CABasicAnimation(keyPath: "transform.scale.y") scaleY.fromValue = startScaleY scaleY.toValue = finalScaleY scaleY.duration = animation.getDuration() - let translationX = CABasicAnimation(keyPath: "translation.x") + let translationX = CABasicAnimation(keyPath: "transform.translation.x") translationX.fromValue = startX translationX.toValue = finalX translationX.duration = animation.getDuration() - let translationY = CABasicAnimation(keyPath: "translation.y") + let translationY = CABasicAnimation(keyPath: "transform.translation.y") translationY.fromValue = startY translationY.toValue = finalY translationY.duration = animation.getDuration() let group = CAAnimationGroup() group.animations = [translationX, translationY, scaleX, scaleY] + group.autoreverses = true + group.repeatCount = 100 let layer = ShapeLayer() + // layer.backgroundColor = UIColor.greenColor().CGColor layer.frame = CGRectMake(0.0, 0.0, 100.0, 100.0) layer.shape = animation.shape layer.setNeedsDisplay() sceneLayer.addSublayer(layer) - layer.addAnimation(group, forKey: .None) + // layer.setAffineTransform(cgTransformFinal) + layer.addAnimation(group, forKey: "flying") } } diff --git a/Source/animation/types/TransformAnimation.swift b/Source/animation/types/TransformAnimation.swift index a5b55993..4f1f393d 100644 --- a/Source/animation/types/TransformAnimation.swift +++ b/Source/animation/types/TransformAnimation.swift @@ -1,7 +1,7 @@ public class TransformAnimation: Animation { - public required init(animatedShape: Shape, observableValue: ObservableValue, startValue: Transform, finalValue: Transform, animationDuration: Double) { + public required init(animatedShape: Group, observableValue: ObservableValue, startValue: Transform, finalValue: Transform, animationDuration: Double) { super.init(observableValue: observableValue, startValue: observableValue.get(), finalValue: finalValue, animationDuration: animationDuration) type = .AffineTransformation shape = animatedShape diff --git a/Source/render/GroupRenderer.swift b/Source/render/GroupRenderer.swift index 656477a9..dd150924 100644 --- a/Source/render/GroupRenderer.swift +++ b/Source/render/GroupRenderer.swift @@ -7,10 +7,12 @@ class GroupRenderer: NodeRenderer { get { return group } } let group: Group + let renderInBounds: Bool - init(group: Group, ctx: RenderContext) { + init(group: Group, ctx: RenderContext, inBounds: Bool = false) { self.group = group self.ctx = ctx + self.renderInBounds = inBounds hook() } @@ -27,7 +29,10 @@ class GroupRenderer: NodeRenderer { contentRenderers.forEach { renderer in if let rendererVal = renderer { CGContextSaveGState(ctx.cgContext) - CGContextConcatCTM(ctx.cgContext, RenderUtils.mapTransform(rendererVal.node.pos)) + if !renderInBounds { + CGContextConcatCTM(ctx.cgContext, RenderUtils.mapTransform(rendererVal.node.pos)) + } + setClip(rendererVal.node) rendererVal.render() CGContextRestoreGState(ctx.cgContext) diff --git a/Source/views/MacawView.swift b/Source/views/MacawView.swift index c90b03fc..f4da720e 100644 --- a/Source/views/MacawView.swift +++ b/Source/views/MacawView.swift @@ -37,5 +37,6 @@ public class MacawView: UIView { // let subscription = AnimationSubscription(animation: animation, paused: !autoPlay) // self.loop?.addSubscription(subscription) animationProducer?.addAnimation(animation) + self.setNeedsDisplay() } } diff --git a/Source/views/ShapeLayer.swift b/Source/views/ShapeLayer.swift index e1c2cb13..978632f9 100644 --- a/Source/views/ShapeLayer.swift +++ b/Source/views/ShapeLayer.swift @@ -1,7 +1,7 @@ import UIKit class ShapeLayer: CALayer { - var shape: Shape? + var shape: Group? override func drawInContext(ctx: CGContext) { guard let shape = shape else { @@ -10,6 +10,6 @@ class ShapeLayer: CALayer { let renderContext = RenderContext(view: .None) renderContext.cgContext = ctx - ShapeRenderer(shape: shape, ctx: renderContext).render() + GroupRenderer(group: shape, ctx: renderContext, inBounds: true).render() } } \ No newline at end of file