1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-10-10 19:37:32 +03:00

Proper animation start and completion

This commit is contained in:
Victor Sukochev 2016-05-16 16:57:14 +02:00
parent 7d3f476a3f
commit e2f948f85a
7 changed files with 42 additions and 18 deletions

View File

@ -22,6 +22,12 @@
574EC4441CBB60AF0063F317 /* AnimationsExampleController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 574EC4431CBB60AF0063F317 /* AnimationsExampleController.swift */; };
575129B61CBD14AF00BD3C2E /* AnimationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 575129B51CBD14AF00BD3C2E /* AnimationsView.swift */; };
575129B81CBD18B800BD3C2E /* PieChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 575129B71CBD18B800BD3C2E /* PieChart.swift */; };
57A9DAB91CEA1502009635C7 /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 57A9DAB81CEA1502009635C7 /* RxSwift.framework */; };
57A9DABA1CEA1502009635C7 /* RxSwift.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 57A9DAB81CEA1502009635C7 /* RxSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
57A9DABC1CEA151E009635C7 /* SWXMLHash.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 57A9DABB1CEA151E009635C7 /* SWXMLHash.framework */; };
57A9DABD1CEA151E009635C7 /* SWXMLHash.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 57A9DABB1CEA151E009635C7 /* SWXMLHash.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
57A9DABF1CEA162F009635C7 /* Swift_CAAnimation_Closure.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 57A9DABE1CEA162F009635C7 /* Swift_CAAnimation_Closure.framework */; };
57A9DAC01CEA162F009635C7 /* Swift_CAAnimation_Closure.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 57A9DABE1CEA162F009635C7 /* Swift_CAAnimation_Closure.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
66AE19D71CC8C7EA00B78B5E /* SVGExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AE19D61CC8C7EA00B78B5E /* SVGExampleViewController.swift */; };
66AE19DB1CC8CB3C00B78B5E /* tiger.svg in Resources */ = {isa = PBXBuildFile; fileRef = 66AE19DA1CC8CB3C00B78B5E /* tiger.svg */; };
B02E75F11C16104900D1971D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02E75F01C16104900D1971D /* AppDelegate.swift */; };
@ -56,7 +62,10 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
57A9DABA1CEA1502009635C7 /* RxSwift.framework in Copy Frameworks */,
B02E76121C16113A00D1971D /* Macaw.framework in Copy Frameworks */,
57A9DABD1CEA151E009635C7 /* SWXMLHash.framework in Copy Frameworks */,
57A9DAC01CEA162F009635C7 /* Swift_CAAnimation_Closure.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@ -79,6 +88,9 @@
574EC4431CBB60AF0063F317 /* AnimationsExampleController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationsExampleController.swift; sourceTree = "<group>"; };
575129B51CBD14AF00BD3C2E /* AnimationsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationsView.swift; sourceTree = "<group>"; };
575129B71CBD18B800BD3C2E /* PieChart.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PieChart.swift; sourceTree = "<group>"; };
57A9DAB81CEA1502009635C7 /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = RxSwift.framework; path = "/Users/Victor/Library/Developer/Xcode/DerivedData/Macaw-avwlwyxpsbzwuxfoqvtfsqmobryt/Build/Products/Release-iphoneos/RxSwift.framework"; sourceTree = "<absolute>"; };
57A9DABB1CEA151E009635C7 /* SWXMLHash.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = SWXMLHash.framework; path = "/Users/Victor/Library/Developer/Xcode/DerivedData/Macaw-avwlwyxpsbzwuxfoqvtfsqmobryt/Build/Products/Release-iphoneos/SWXMLHash.framework"; sourceTree = "<absolute>"; };
57A9DABE1CEA162F009635C7 /* Swift_CAAnimation_Closure.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Swift_CAAnimation_Closure.framework; path = "/Users/Victor/Library/Developer/Xcode/DerivedData/Macaw-avwlwyxpsbzwuxfoqvtfsqmobryt/Build/Products/Release-iphoneos/Swift_CAAnimation_Closure.framework"; sourceTree = "<absolute>"; };
66AE19D61CC8C7EA00B78B5E /* SVGExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SVGExampleViewController.swift; path = SVG/SVGExampleViewController.swift; sourceTree = "<group>"; };
66AE19DA1CC8CB3C00B78B5E /* tiger.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = tiger.svg; path = Example/Assets/SVG/tiger.svg; sourceTree = "<group>"; };
B02E75ED1C16104900D1971D /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -95,7 +107,10 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
57A9DAB91CEA1502009635C7 /* RxSwift.framework in Frameworks */,
B02E76101C16111D00D1971D /* Macaw.framework in Frameworks */,
57A9DABC1CEA151E009635C7 /* SWXMLHash.framework in Frameworks */,
57A9DABF1CEA162F009635C7 /* Swift_CAAnimation_Closure.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -214,6 +229,9 @@
B02E75E41C16104900D1971D = {
isa = PBXGroup;
children = (
57A9DABE1CEA162F009635C7 /* Swift_CAAnimation_Closure.framework */,
57A9DABB1CEA151E009635C7 /* SWXMLHash.framework */,
57A9DAB81CEA1502009635C7 /* RxSwift.framework */,
66AE19D81CC8CAB000B78B5E /* Assets */,
24BE06FF1C6B91C800B5882F /* img */,
B02E75EF1C16104900D1971D /* Example */,

View File

@ -232,7 +232,7 @@ class PathExampleView: MacawView {
*/
let n = 200
let n = 40
// let g = 800.0
var clouds = [Node]()
for _ in 0 ... (n - 1) {
@ -241,8 +241,8 @@ class PathExampleView: MacawView {
y: -700 + Double(rand() % 1400))
let flying = TransformAnimation(animatedShape: cloud,
observableValue: cloud.posVar,
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),
startValue: Transform(),
finalValue: Transform.move(velocity.x, my: velocity.y).scale(1.0, sy: 1.0),
animationDuration: 4.0)
animation.append(flying)
clouds.append(cloud)

View File

@ -34,12 +34,16 @@ public class AnimationProducer {
let cgTransformStart = transfomToCG(transformAnimation.start)
let cgTransformFinal = transfomToCG(transformAnimation.final)
let cgInitialTransform = transfomToCG(shape.pos)
// Small workaround
let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
let initRect = CGRectApplyAffineTransform(rect, cgInitialTransform)
let startRect = CGRectApplyAffineTransform(rect, cgTransformStart)
let finalRect = CGRectApplyAffineTransform(rect, cgTransformFinal)
let initScaleX = initRect.width
let initScaleY = initRect.height
let startX = startRect.origin.x
let startY = startRect.origin.y
let finalX = finalRect.origin.x
@ -81,28 +85,34 @@ public class AnimationProducer {
// layer.backgroundColor = UIColor.greenColor().CGColor
// layer.borderWidth = 1.0
// layer.borderColor = UIColor.blueColor().CGColor
unowned let uSelf = self
group.completion = { finished in
if !finished {
return
}
layer.removeFromSuperlayer()
animation.shape?.animating = false
uSelf.sceneLayer.setNeedsDisplay()
}
if let shapeBounds = shape.bounds() {
print("Shape bounds: \(shapeBounds.description())")
let cgRect = shapeBounds.cgRect()
layer.frame = CGRectMake(0.0, 0.0,
let origFrame = CGRectMake(0.0, 0.0,
cgRect.width + cgRect.origin.x,
cgRect.height + cgRect.origin.y)
// layer.frame = origFrame
layer.frame = CGRectApplyAffineTransform(origFrame, cgInitialTransform)
layer.renderTransform = CGAffineTransformMakeScale(initScaleX, initScaleY)
}
layer.shape = shape
layer.setNeedsDisplay()
sceneLayer.addSublayer(layer)
// layer.setAffineTransform(cgTransformFinal)
layer.addAnimation(group, forKey: "flying")
}
}

View File

@ -10,10 +10,6 @@ func pathBounds(path: Path) -> Rect? {
var currentPoint = firstSegmentInfo.1 ?? Point.zero()
var cubicBezierPoint: Point?
print("New path - \(path.segments.count) segments")
print("Initial bounds \(bounds!.description())")
print("Initial point \(currentPoint.description())")
for segment in path.segments {
let segmentInfo = pathSegmenInfo(segment, currentPoint: currentPoint, currentBezierPoint: cubicBezierPoint)
if let segmentBounds = segmentInfo.0 {
@ -25,8 +21,6 @@ func pathBounds(path: Path) -> Rect? {
}
}
print("Total bounds \(bounds!.description())")
if let segmentLastPoint = segmentInfo.1 {
if segment.absolute {
currentPoint = segmentLastPoint
@ -42,8 +36,6 @@ func pathBounds(path: Path) -> Rect? {
cubicBezierPoint = segmentBezierPoint.add(currentPoint)
}
}
print("Updated point \(currentPoint.description())")
}
return bounds

View File

@ -3,7 +3,7 @@ import RxSwift
public class TransformAnimation: Animation<Transform> {
public required init(animatedShape: Group, observableValue: Variable<Transform>, startValue: Transform, finalValue: Transform, animationDuration: Double) {
super.init(observableValue: observableValue, startValue: observableValue.value, finalValue: finalValue, animationDuration: animationDuration)
super.init(observableValue: observableValue, startValue: startValue, finalValue: finalValue, animationDuration: animationDuration)
type = .AffineTransformation
shape = animatedShape
}

View File

@ -34,9 +34,7 @@ public class Group: Node {
return
}
print("Node bounds: \(nodeBounds.description())")
union = union.union(nodeBounds.applyTransform(node.pos))
print("Union after transformation: \(union.description())")
}
return union // .applyTransform(pos)

View File

@ -2,6 +2,7 @@ import UIKit
class ShapeLayer: CALayer {
var shape: Group?
var renderTransform: CGAffineTransform?
override func drawInContext(ctx: CGContext) {
guard let shape = shape else {
@ -10,6 +11,11 @@ class ShapeLayer: CALayer {
let renderContext = RenderContext(view: .None)
renderContext.cgContext = ctx
if let renderTransform = renderTransform {
CGContextConcatCTM(ctx, renderTransform)
}
GroupRenderer(group: shape, ctx: renderContext).render()
}
}