@@ -1,3 +1,6 @@
1+
2+import Darwin
3+
14func interpolateCubeEaseIn<T: Numeric>(linear: T) -> T {
25 return linear ^ 3
36}
@@ -13,3 +16,61 @@ func interpolateSquareEaseOut<T: Numeric>(linear: T) -> T {
1316func interpolateSmooth<T: Numeric>(linear: T) -> T {
1417 return ((linear) * (linear) * (linear) * ((linear) * ((linear) * 6 - 15) + 10))
1518}
19+
20+func createStringKeyframes(bounces: Int = 2, elasticity: Double = 1.1, bounceSpeed: Double) -> [(time: Double, position: Double)] {
21+ // Setup keyframes
22+ var keyFrames: [(time: Double, position: Double)] = [(1, 1)]
23+
24+ let overreach = elasticity - 1
25+
26+ var currentBounceTime: Double = overreach / (bounceSpeed ^ Double(bounces))
27+ var bounceDirection = Double((bounces % 2) * 2 - 1)
28+ var bounceReach = overreach / (2 ^ Double(bounces - 1))
29+ var currentBouncePosition: Double = 1.0 + bounceDirection * bounceReach
30+
31+ print(currentBounceTime)
32+ print(bounceDirection)
33+ print(bounceReach)
34+ print(currentBouncePosition)
35+
36+ keyFrames.append((1.0 - currentBounceTime, currentBouncePosition))
37+
38+ for i in (1..<bounces).reverse() {
39+ currentBounceTime += overreach / (bounceSpeed ^ Double(i + 1))
40+ currentBounceTime += overreach / (bounceSpeed ^ Double(i))
41+ bounceDirection = Double((i % 2) * 2 - 1)
42+ bounceReach = overreach / (2 ^ Double(i - 1))
43+ currentBouncePosition = 1.0 + bounceDirection * bounceReach
44+
45+ keyFrames.append((1.0 - currentBounceTime, currentBouncePosition))
46+
47+ print(currentBounceTime)
48+ print(bounceDirection)
49+ print(bounceReach)
50+ print(currentBouncePosition)
51+ }
52+
53+ keyFrames.append((0, 0))
54+
55+ var reversed = [(time: Double, position: Double)]()
56+ for keyFrame in keyFrames.reverse() {
57+ reversed.append(keyFrame)
58+ }
59+
60+ return reversed
61+}
62+
63+func interpolateSpring<T: Numeric>(linear: T, bounces: Int = 2, elasticity: Double = 1.1, bounceSpeed: Double = 1.0) -> T {
64+ let keyFrames: [(time: Double, position: Double)]
65+ keyFrames = createStringKeyframes(bounces, elasticity: elasticity, bounceSpeed: bounceSpeed)
66+
67+ let x = linear.toDouble
68+
69+ let startFrame = keyFrames.filter { $0.time < x }.last ?? (0, 0)
70+ let endFrame = keyFrames.filter { $0.time > x }.first ?? (1, 1)
71+ let adjustedX = (x - startFrame.time) / (endFrame.time - startFrame.time)
72+ let interpolatedX = interpolateSmooth(adjustedX)
73+ let position = startFrame.position + interpolatedX * (endFrame.position - startFrame.position)
74+
75+ return T.fromDouble(position)
76+}