Advertisement
Guest User

Untitled

a guest
Oct 13th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.43 KB | None | 0 0
  1. //
  2. // ContentView.swift
  3. // AnimationTimingCurve
  4. //
  5. // Created by Chris Eidhof on 25.09.19.
  6. // Copyright © 2019 Chris Eidhof. All rights reserved.
  7. //
  8.  
  9. import SwiftUI
  10.  
  11. struct RecordTimingCurve: GeometryEffect {
  12. var onChange: (CGFloat) -> () = { _ in () }
  13. var animatableData: CGFloat = 0 {
  14. didSet {
  15. onChange(animatableData)
  16. }
  17. }
  18.  
  19. func effectValue(size: CGSize) -> ProjectionTransform {
  20. return .init()
  21. }
  22. }
  23.  
  24. import Combine
  25.  
  26. final class AnimationTrace: ObservableObject {
  27. let objectWillChange = PassthroughSubject<(), Never>()
  28. var data: [(time: CFTimeInterval, value: CGFloat)] = []
  29.  
  30. var startTime: CFTimeInterval {
  31. data.first?.time ?? 0
  32. }
  33.  
  34. var endTime: CFTimeInterval {
  35. data.last?.time ?? 0
  36. }
  37.  
  38. func record(_ value: CGFloat) {
  39. data.append((CACurrentMediaTime(), value))
  40. // if value == 1 {
  41. DispatchQueue.main.async {
  42. print("Data count: \(self.data.count)")
  43. self.objectWillChange.send()
  44. }
  45. // }
  46. }
  47. func reset() {
  48. data = []
  49. }
  50. }
  51.  
  52. struct Trace: Shape {
  53. var values: [(CGFloat, CGFloat)] // the second component should be in range 0...1
  54.  
  55. func path(in rect: CGRect) -> Path {
  56. guard let f = values.first, let l = values.last else { return Path() }
  57. let xOffset = f.0
  58. let xMultiplier = l.0 - f.0
  59. return Path { p in
  60. p.move(to: CGPoint(x: rect.minX, y: rect.maxY))
  61. for value in values {
  62. let point = CGPoint(x: rect.minX + ((value.0 - xOffset) / xMultiplier) * rect.width, y: rect.maxY - CGFloat(value.1) * rect.height)
  63. p.addLine(to: point)
  64. }
  65. }
  66. }
  67.  
  68. }
  69.  
  70. let animations: [(String, Animation)] = [
  71. ("default", .default),
  72. ("linear(duration: 1)", .linear(duration: 1)),
  73. ("interpolatingSpring(stiffnes: 5, damping: 3)", .interpolatingSpring(stiffness: 5, damping: 3)),
  74. (".easeInOut(duration: 1)", .easeInOut(duration: 1)),
  75. (".easeIn(duration: 1)", .easeIn(duration: 1)),
  76. (".easeOut(duration: 1)", .easeOut(duration: 1)),
  77. (".interactiveSpring(response: 3, dampingFraction: 2, blendDuration: 1)", .interactiveSpring(response: 3, dampingFraction: 2, blendDuration: 1)),
  78. (".spring", .spring()),
  79. (".default.repeatCount(3)", Animation.default.repeatCount(3)),
  80. ]
  81.  
  82. struct ContentView: View {
  83. @ObservedObject var trace = AnimationTrace()
  84. @State var animating: Bool = false
  85. @State var selectedAnimationIndex: Int = 0
  86. @State var slowAnimations: Bool = false
  87. var selectedAnimation: (String, Animation) {
  88. return animations[selectedAnimationIndex]
  89. }
  90. var body: some View {
  91. VStack {
  92. RoundedRectangle(cornerRadius: 10)
  93. .fill(Color.pink)
  94. .frame(width: 50, height: 50)
  95. .offset(x: animating ? 100 : -100)
  96. .modifier(RecordTimingCurve(onChange: {
  97. self.trace.record($0)
  98. }, animatableData: animating ? 1 : 0))
  99. VStack {
  100. Trace(values: trace.data.map {
  101. (CGFloat($0), $1)
  102. })
  103. .stroke(Color.red, style: .init(lineWidth: 2))
  104. .frame(height: 150)
  105. .background(Rectangle().stroke(Color.gray, style: .init(lineWidth: 1)))
  106. HStack {
  107. Text("0")
  108. Spacer()
  109. Text("\(trace.endTime - trace.startTime)")
  110.  
  111. }
  112. }.frame(width: 200)
  113.  
  114. Spacer()
  115. Picker(selection: $selectedAnimationIndex, label: EmptyView(), content: {
  116. ForEach(0..<animations.count) {
  117. Text(animations[$0].0)
  118. }
  119. })
  120.  
  121. Button(action: {
  122. self.animating = false
  123. self.trace.reset()
  124. withAnimation(self.selectedAnimation.1.speed(self.slowAnimations ? 0.25 : 1), {
  125. self.animating = true
  126. })
  127. }, label: { Text("Animate") })
  128. Toggle(isOn: $slowAnimations, label: { Text("Slow Animations") })
  129. }
  130. }
  131. }
  132.  
  133. struct ContentView_Previews: PreviewProvider {
  134. static var previews: some View {
  135. ContentView()
  136. }
  137. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement