Skip to content

Instantly share code, notes, and snippets.

@bolivarbryan
Created July 26, 2020 19:44
Show Gist options
  • Save bolivarbryan/d8848c0dff7be242b80565f5ea5077a4 to your computer and use it in GitHub Desktop.
Save bolivarbryan/d8848c0dff7be242b80565f5ea5077a4 to your computer and use it in GitHub Desktop.
import SwiftUI
struct BounceEffect: GeometryEffect{
var height: CGFloat
var times: CGFloat
init(height: CGFloat = 50, times: Int) {
self.height = height
self.times = CGFloat(times)
}
var animatableData: CGFloat {
get { times }
set { times = newValue }
}
private func bounceY(_ x: CGFloat) -> CGFloat {
abs(sin(x * .pi))
}
func effectValue(size: CGSize) -> ProjectionTransform {
ProjectionTransform(.init(translationX: 0, y: -height * bounceY(times)))
}
}
struct Bounce: AnimatableModifier {
var height: CGFloat
var times: CGFloat
init(height: CGFloat = 50, times: Int) {
self.height = height
self.times = CGFloat(times)
}
var animatableData: CGFloat {
get { times }
set { times = newValue }
}
func body(content: Content) -> some View {
content
.transformEffect(.init(translationX: 0,
y: -height * bounceY(times)))
}
private func bounceY(_ x: CGFloat) -> CGFloat {
abs(sin(x * .pi))
}
}
extension View {
func bounce(_ n: Int) -> some View {
modifier(BounceEffect(times: n))
}
}
struct ContentView: View {
// @State var rotationAngle = Angle(degrees: 0)
@State var bounces: Int = 0
var body: some View {
VStack {
Image(systemName: "star.fill")
.font(.largeTitle)
.foregroundColor(.orange)
.bounce(bounces)
.animation(Animation.linear(duration: 2))
Button(action: {
bounces += 3
}, label: {
Text("Animate!")
})
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment