mirror of
https://github.com/exyte/Macaw.git
synced 2024-10-11 03:49:05 +03:00
Proper animation start and completion
This commit is contained in:
parent
7d3f476a3f
commit
e2f948f85a
@ -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 */,
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user