Skip to content

Instantly share code, notes, and snippets.

@dqhieu
Last active April 6, 2023 00:50
Show Gist options
  • Save dqhieu/4a9f9bb45a5cbfd2bf93badff9ed3388 to your computer and use it in GitHub Desktop.
Save dqhieu/4a9f9bb45a5cbfd2bf93badff9ed3388 to your computer and use it in GitHub Desktop.
Twitter's new animation ❤️
struct ContentView: View {
@State var scale: CGFloat = 0
@State var showingBlankHeart = true
@State var heartScale: CGFloat = 0
@State var textOpacity: Double = 1
@State var offset1: CGFloat = 0
@State var plus1Opacity: Double = 1
@State var offset2: CGFloat = 0
@State var plus2Opacity: Double = 1
@State var offset3: CGFloat = 0
@State var plus3Opacity: Double = 1
var body: some View {
VStack {
Spacer()
ZStack {
Image(systemName: "plus")
.resizable()
.frame(width: 12, height: 12, alignment: .center)
.font(.system(size: 16, weight: .bold, design: .rounded))
.foregroundColor(.red)
.offset(x: 0, y: offset1)
.opacity(plus1Opacity)
.padding(.bottom, 0)
.padding(.trailing, 20)
Image(systemName: "plus")
.resizable()
.frame(width: 12, height: 12, alignment: .center)
.font(.system(size: 16, weight: .bold, design: .rounded))
.foregroundColor(.red)
.offset(x: 0, y: offset2)
.opacity(plus2Opacity)
.padding(.bottom, 20)
Image(systemName: "plus")
.resizable()
.frame(width: 12, height: 12, alignment: .center)
.font(.system(size: 16, weight: .bold, design: .rounded))
.foregroundColor(.red)
.offset(x: 0, y: offset3)
.opacity(plus3Opacity)
.padding(.bottom, 00)
.padding(.trailing, -20)
Circle()
.frame(width: 36, height: 36, alignment: .center)
.foregroundColor(Color.white)
Circle()
.frame(width: 35, height: 35, alignment: .center)
.foregroundColor(Color.red)
.scaleEffect(scale)
.animation(.spring())
Circle()
.frame(width: 36, height: 36, alignment: .center)
.foregroundColor(Color.white)
.scaleEffect(scale)
.animation(.spring().delay(0.3))
if showingBlankHeart {
Image(systemName: "heart")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
Image(systemName: "heart.fill")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
.foregroundColor(.red)
.scaleEffect(heartScale)
Text("+1")
.foregroundColor(.white)
.font(.system(size: 16, weight: .bold, design: .rounded))
.scaleEffect(heartScale)
.opacity(textOpacity)
}
Button(action: {
showingBlankHeart = false
scale = 1
withAnimation(.interpolatingSpring(
mass: 1,
stiffness: 100,
damping: 10,
initialVelocity: 2).delay(0.5)) {
heartScale = 1
}
withAnimation(.easeInOut(duration: 0.5).delay(1.5)) {
textOpacity = 0
}
withAnimation(.easeInOut(duration: 1).delay(0.5)) {
offset1 = -30
plus1Opacity = 0
}
withAnimation(.easeInOut(duration: 1).delay(0.8)) {
offset2 = -30
plus2Opacity = 0
}
withAnimation(.easeInOut(duration: 1).delay(1)) {
offset3 = -30
plus3Opacity = 0
}
}, label: {
Text("Start")
})
.padding()
Button(action: {
showingBlankHeart = true
scale = 0
heartScale = 0
textOpacity = 1
offset1 = 0
plus1Opacity = 1
offset2 = 0
plus2Opacity = 1
offset3 = 0
plus3Opacity = 1
}, label: {
Text("Reset")
})
.padding()
Spacer()
}
}
}
@dqhieu
Copy link
Author

dqhieu commented May 25, 2021

My naive implementation of Twitter's animation, check out here https://twitter.com/dqhieu/status/1397194024595992576?s=20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment