Skip to content

Instantly share code, notes, and snippets.

@TAATHub
Last active March 7, 2025 13:53
Show Gist options
  • Save TAATHub/a34152d8563a54c2a9027fc0c05bb2af to your computer and use it in GitHub Desktop.
Save TAATHub/a34152d8563a54c2a9027fc0c05bb2af to your computer and use it in GitHub Desktop.
aaaaaa
import SwiftUI
struct AnimatedLikeView: View {
@State private var isFavorite = false
var body: some View {
VStack(spacing: 60) {
Button {
withAnimation(.none) {
isFavorite.toggle()
}
} label: {
if isFavorite {
Image(systemName: "heart.fill")
.foregroundStyle(.blue)
.transition(.confetti(color: .blue, size: 5))
} else {
Image(systemName: "heart")
.foregroundStyle(.gray)
}
}
.font(.system(size: 128))
}
}
}
#Preview {
AnimatedLikeView()
}
import SwiftUI
struct ConfettiModifier: ViewModifier {
@State private var circleSize = 0.00001
@State private var strokeMultipler: CGFloat = 1.0
@State private var confettiIsHidden = true
@State private var confettiMovement = 0.7
@State private var confettiScale = 1.0
@State private var contentsScale = 0.00001
private let speed = 0.3
var color: Color
var size: Double
func body(content: Content) -> some View {
content
.hidden()
.padding(10)
.overlay(
ZStack {
GeometryReader { proxy in
Circle()
.strokeBorder(color, lineWidth: proxy.size.width / 2 * strokeMultipler)
.scaleEffect(circleSize)
ForEach(0..<15) { i in
Circle()
.fill(color)
.frame(width: size + sin(Double(i)), height: size + sin(Double(i)))
.scaleEffect(confettiScale)
.offset(x: proxy.size.width / 2 * confettiMovement + (i.isMultiple(of: 2) ? size : 0))
.rotationEffect(.degrees(24 * Double(i)))
.offset(x: (proxy.size.width - size) / 2, y: (proxy.size.height - size) / 2)
.opacity(confettiIsHidden ? 0 : 1)
}
}
content
.scaleEffect(contentsScale)
}
)
.padding(-10)
.onAppear {
withAnimation(.easeIn(duration: speed)) {
circleSize = 1
}
withAnimation(.easeOut(duration: speed).delay(speed)) {
strokeMultipler = 0.00001
}
withAnimation(.easeOut(duration: speed).delay(speed * 1.25)) {
confettiIsHidden = false
confettiMovement = 1.2
}
withAnimation(.easeOut(duration: speed).delay(speed * 2)) {
confettiScale = 0.00001
}
withAnimation(.interpolatingSpring(stiffness: 50, damping: 5).delay(speed)) {
contentsScale = 1
}
}
}
}
extension AnyTransition {
static var confetti: AnyTransition {
.modifier(
active: ConfettiModifier(color: .blue, size: 3),
identity: ConfettiModifier(color: .blue, size: 3)
)
}
static func confetti(color: Color = .blue, size: Double = 3.0) -> AnyTransition {
AnyTransition.modifier(
active: ConfettiModifier(color: color, size: size),
identity: ConfettiModifier(color: color, size: size)
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment