1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-11 13:15:35 +03:00

Resolve #58: make from property of animation optional

This commit is contained in:
Yuri Strot 2016-09-23 00:56:02 +07:00
parent f2df3c956b
commit f5bcb7098c
7 changed files with 119 additions and 76 deletions

View File

@ -72,7 +72,7 @@ class AnimationsView: MacawView {
velocities.append(velocity)
positions.append(Point(x: 0.0, y: 0.0))
let anim = ballGroup.placeVar.animation(valueFunc: { t -> Transform in
let anim = ballGroup.placeVar.animation({ t -> Transform in
let pos = posForTime(t, index: i)
positions[i] = pos

View File

@ -3,30 +3,33 @@ public class Animation {
internal init() {
}
public func cycle(count count: Double) -> Animation {
public func play() {
}
public func stop() {
}
public func easing(easing: Easing) -> Animation {
return self
}
public func delay(delay: Double) -> Animation {
return self
}
public func cycle(count: Double) -> Animation {
return self
}
public func reverse() -> Animation {
return self
}
public func autoreversed() -> Animation {
return self
}
public func easing(easing: Easing) -> Animation {
return self
}
public func onComplete(_: (() -> ())) -> Animation {
return self
}
public func play() {
}
public func stop() {
}
public func reverse() -> Animation {
return self
}
}

View File

@ -38,7 +38,12 @@ class BasicAnimation: Animation {
super.init()
}
override public func cycle(count count: Double) -> Animation {
override public func delay(delay: Double) -> Animation {
self.delay += delay
return self
}
override public func cycle(count: Double) -> Animation {
self.repeatCount = count
return self
}
@ -78,13 +83,16 @@ class BasicAnimation: Animation {
internal class AnimationImpl<T: Interpolable>: BasicAnimation {
let value: Variable<T>
let vFunc: ((Double) -> T)
let timeFactory: ((Node) -> ((Double) -> T))
let duration: Double
let logicalFps: UInt
private var vFunc: ((Double) -> T)?
init(observableValue: Variable<T>, valueFunc: (Double) -> T, animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) {
self.value = observableValue
self.duration = animationDuration
self.timeFactory = { (node) in return valueFunc }
self.vFunc = valueFunc
self.logicalFps = fps
@ -92,6 +100,17 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
self.delay = delay
}
init(observableValue: Variable<T>, factory: ((Node) -> ((Double) -> T)), animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) {
self.value = observableValue
self.duration = animationDuration
self.timeFactory = factory
self.logicalFps = fps
super.init()
self.delay = delay
}
convenience init(observableValue: Variable<T>, startValue: T, finalValue: T, animationDuration: Double) {
let interpolationFunc = { (t: Double) -> T in
@ -109,6 +128,13 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
return duration
}
public func getVFunc() -> ((Double) -> T) {
if (vFunc == nil) {
vFunc = timeFactory(self.node!)
}
return vFunc!
}
}
// For sequence completion

View File

@ -21,15 +21,27 @@ internal class OpacityAnimation: AnimationImpl<Double> {
self.play()
}
}
init(animatedNode: Node, factory: ((Node) -> ((Double) -> Double)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
super.init(observableValue: animatedNode.opacityVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
type = .Opacity
node = animatedNode
if autostart {
self.play()
}
}
public override func reverse() -> Animation {
let reversedFunc = { (t: Double) -> Double in
return self.vFunc(1.0 - t)
}
let factory = { (node: Node) -> (Double) -> Double in
let original = self.timeFactory(node)
return { (t: Double) -> Double in
return original(1.0 - t)
}
}
let reversedAnimation = OpacityAnimation(animatedNode: node!,
valueFunc: reversedFunc, animationDuration: duration, fps: logicalFps)
factory: factory, animationDuration: duration, fps: logicalFps)
reversedAnimation.progress = progress
reversedAnimation.completion = completion
@ -40,37 +52,31 @@ internal class OpacityAnimation: AnimationImpl<Double> {
public typealias OpacityAnimationDescription = AnimationDescription<Double>
public extension AnimatableVariable where T: DoubleInterpolation {
// public func animate(desc: AnimationDescription<T: Double>) {
public func animate(desc: OpacityAnimationDescription) {
guard let node = self.node else {
return
}
let _ = OpacityAnimation(animatedNode: node, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
let _ = OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
}
public func animation(desc: OpacityAnimationDescription) -> Animation {
guard let node = self.node else {
return EmptyAnimation(completion: { })
}
return OpacityAnimation(animatedNode: node, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
return OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
}
public func animate(from from: Double, to: Double, during: Double, delay: Double = 0.0) {
self.animate((from >> to).t(during, delay: delay))
public func animate(from from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) {
self.animate(((from ?? node!.opacity) >> to).t(during, delay: delay))
}
public func animation(from from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) -> Animation {
if let safeFrom = from {
return self.animation((safeFrom >> to).t(during, delay: delay))
}
let factory = { (node: Node) -> (Double) -> Double in
let from = node.opacity
return { (t: Double) in return from.interpolate(to, progress: t) }
}
return OpacityAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay)
}
public func animation(from from: Double, to: Double, during: Double, delay: Double = 0.0) -> Animation {
return self.animation((from >> to).t(during, delay: delay))
}
public func animation(valueFunc valueFrunc: (Double) -> Double, during: Double, delay: Double = 0.0) -> Animation {
guard let node = self.node else {
return EmptyAnimation(completion: { })
}
return OpacityAnimation(animatedNode: node, valueFunc: valueFrunc, animationDuration: during, delay: delay)
public func animation(f: (Double) -> Double, during: Double = 1.0, delay: Double = 0.0) -> Animation {
return OpacityAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
}
}

View File

@ -20,15 +20,28 @@ internal class TransformAnimation: AnimationImpl<Transform> {
self.play()
}
}
init(animatedNode: Node, factory: ((Node) -> ((Double) -> Transform)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
super.init(observableValue: animatedNode.placeVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
type = .AffineTransformation
node = animatedNode
if autostart {
self.play()
}
}
public override func reverse() -> Animation {
let reversedFunc = { (t: Double) -> Transform in
return self.vFunc(1.0 - t)
}
let factory = { (node: Node) -> (Double) -> Transform in
let original = self.timeFactory(node)
return { (t: Double) -> Transform in
return original(1.0 - t)
}
}
let reversedAnimation = TransformAnimation(animatedNode: node!,
valueFunc: reversedFunc, animationDuration: duration, fps: logicalFps)
factory: factory, animationDuration: duration, fps: logicalFps)
reversedAnimation.progress = progress
reversedAnimation.completion = completion
@ -40,35 +53,30 @@ public typealias TransformAnimationDescription = AnimationDescription<Transform>
public extension AnimatableVariable where T: TransformInterpolation {
public func animate(desc: TransformAnimationDescription) {
guard let node = self.node else {
return
}
let _ = TransformAnimation(animatedNode: node, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
let _ = TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
}
public func animation(desc: TransformAnimationDescription) -> Animation {
guard let node = self.node else {
return EmptyAnimation(completion: { })
}
return TransformAnimation(animatedNode: node, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
return TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
}
public func animate(from from: Transform? = nil, to: Transform, during: Double, delay: Double = 0.0) {
public func animate(from from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) {
self.animate(((from ?? node!.place) >> to).t(during, delay: delay))
}
public func animation(from from: Transform, to: Transform, during: Double, delay: Double = 0.0) -> Animation {
return self.animation((from >> to).t(during, delay: delay))
public func animation(from from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) -> Animation {
if let safeFrom = from {
return self.animation((safeFrom >> to).t(during, delay: delay))
}
let factory = { (node: Node) -> (Double) -> Transform in
let from = node.place
return { (t: Double) in return from.interpolate(to, progress: t) }
}
return TransformAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay)
}
public func animation(valueFunc valueFrunc: (Double) -> Transform, during: Double, delay: Double = 0.0) -> Animation {
guard let node = self.node else {
return EmptyAnimation(completion: { })
}
return TransformAnimation(animatedNode: node, valueFunc: valueFrunc, animationDuration: during, delay: delay)
public func animation(f: (Double) -> Transform, during: Double, delay: Double = 0.0) -> Animation {
return TransformAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
}
}

View File

@ -11,7 +11,7 @@ func addOpacityAnimation(animation: BasicAnimation, sceneLayer: CALayer, animati
}
// Creating proper animation
let generatedAnimation = opacityAnimationByFunc(opacityAnimation.vFunc, duration: animation.getDuration(), fps: opacityAnimation.logicalFps)
let generatedAnimation = opacityAnimationByFunc(opacityAnimation.getVFunc(), duration: animation.getDuration(), fps: opacityAnimation.logicalFps)
generatedAnimation.autoreverses = animation.autoreverses
generatedAnimation.repeatCount = Float(animation.repeatCount)
generatedAnimation.timingFunction = caTimingFunction(animation.easing)
@ -21,7 +21,7 @@ func addOpacityAnimation(animation: BasicAnimation, sceneLayer: CALayer, animati
animationCache.freeLayer(node)
animation.progress = 1.0
node.opacityVar.value = opacityAnimation.vFunc(1.0)
node.opacityVar.value = opacityAnimation.getVFunc()(1.0)
animation.completion?()
@ -36,7 +36,7 @@ func addOpacityAnimation(animation: BasicAnimation, sceneLayer: CALayer, animati
generatedAnimation.progress = { progress in
let t = Double(progress)
node.opacityVar.value = opacityAnimation.vFunc(t)
node.opacityVar.value = opacityAnimation.getVFunc()(t)
animation.progress = t
animation.onProgressUpdate?(t)

View File

@ -12,7 +12,7 @@ func addTransformAnimation(animation: BasicAnimation, sceneLayer: CALayer, anima
// Creating proper animation
var generatedAnimation: CAAnimation?
generatedAnimation = transformAnimationByFunc(node, valueFunc: transformAnimation.vFunc, duration: animation.getDuration(), fps: transformAnimation.logicalFps)
generatedAnimation = transformAnimationByFunc(node, valueFunc: transformAnimation.getVFunc(), duration: animation.getDuration(), fps: transformAnimation.logicalFps)
guard let generatedAnim = generatedAnimation else {
return
@ -25,7 +25,7 @@ func addTransformAnimation(animation: BasicAnimation, sceneLayer: CALayer, anima
generatedAnim.completion = { finished in
animation.progress = 1.0
node.placeVar.value = transformAnimation.vFunc(1.0)
node.placeVar.value = transformAnimation.getVFunc()(1.0)
animationCache.freeLayer(node)
animation.completion?()
@ -41,7 +41,7 @@ func addTransformAnimation(animation: BasicAnimation, sceneLayer: CALayer, anima
generatedAnim.progress = { progress in
let t = Double(progress)
node.placeVar.value = transformAnimation.vFunc(t)
node.placeVar.value = transformAnimation.getVFunc()(t)
animation.progress = t
animation.onProgressUpdate?(t)