material-motion / material-motion-swift

A toolkit for building responsive motion using Core Animation.
Apache License 2.0
1.42k stars 79 forks source link

Not easy to apply an impulse to make an object "bounce" with core animation #48

Open jverkoey opened 7 years ago

jverkoey commented 7 years ago

Consider the following interaction:

let spring = Spring<CGFloat>(threshold: 0.01, system: coreAnimation)
spring.initialVelocity.value = 10
spring.destination.value = 1
runtime.add(spring, to: runtime.get(square.layer).scale)

When using POP, this would behave as expected; the view would scale outward somewhat and eventually settle back at 1. This is because POP looks at the overall energy in the system to determine completeness.

When using Core Animation, however, this animation does nothing. This is because Core Animation thinks of velocity only relative to the distance to be traveled (in this case 0), so the animation ends up nooping.

I'm not sure whether there's a clear fix here, but I'll explore some hackfixes.

jverkoey commented 7 years ago

Here's my hack solution:

let spring = Spring<CGFloat>(threshold: 0.01, system: coreAnimation)
spring.destination.value = 1
runtime.add(spring, to: runtime.get(square.layer).scale)

let tap = runtime.get(UITapGestureRecognizer())
runtime.connect(tap.whenRecognitionState(is: .recognized).rewriteTo(1.5), to: spring.destination)
runtime.connect(tap.whenRecognitionState(is: .recognized).delay(by: 0.1).rewriteTo(1), to: spring.destination)