Skip to content

Instantly share code, notes, and snippets.

@amosgyamfi
Created December 11, 2025 23:59
Show Gist options
  • Select an option

  • Save amosgyamfi/d7657668027ac27803e5c4aa23db1b8b to your computer and use it in GitHub Desktop.

Select an option

Save amosgyamfi/d7657668027ac27803e5c4aa23db1b8b to your computer and use it in GitHub Desktop.
//
// ListeningVoiceAnimation.swift
//
// Created by Amos Gyamfi on 12.12.2025.
//
import SwiftUI
struct ListeningVoiceAnimation: View {
var body: some View {
ZStack {
Image("shadow")
Image("icon-bg")
PhaseAnimator([false ,true]) { animatePinkTop in
Image("pink-top")
.rotationEffect(.degrees(animatePinkTop ? 320 : -360))
.hueRotation(.degrees(animatePinkTop ? -270 : 60))
} animation: { animatePinkTop in
.easeIn(duration: 12).repeatForever(autoreverses: false)
}
PhaseAnimator([false ,true]) { animatePinkLeft in
Image("pink-left")
.rotationEffect(.degrees(animatePinkLeft ? -360 : 180))
.hueRotation(.degrees(animatePinkLeft ? -220 : 300))
} animation: { animatePinLeft in
.easeOut(duration: 12).repeatForever(autoreverses: false)
}
PhaseAnimator([false ,true]) { animateBlueMiddle in
Image("blue-middle")
.rotationEffect(.degrees(animateBlueMiddle ? -360 : 420))
.hueRotation(.degrees(animateBlueMiddle ? -150 : 0))
.rotation3DEffect(.degrees(75), axis: (x: animateBlueMiddle ? 1 : 5, y: 0, z: 0))
} animation: { animateBlueMiddle in
.easeInOut(duration: 12).repeatForever(autoreverses: false)
}
PhaseAnimator([false ,true]) { animateBlueRight in
Image("blue-right")
.rotationEffect(.degrees(animateBlueRight ? -360 : 420))
.hueRotation(.degrees(animateBlueRight ? 720 : -50))
.rotation3DEffect(.degrees(75), axis: (x: 1, y: 0, z: animateBlueRight ? -5 : 15))
} animation: { animateBlueRight in
.easeIn(duration: 12).repeatForever(autoreverses: false)
}
PhaseAnimator([false ,true]) { animateIntersect in
Image("intersect")
.rotationEffect(.degrees(animateIntersect ? 30 : -420))
.hueRotation(.degrees(animateIntersect ? 0 : 720))
.rotation3DEffect(.degrees(15), axis: (x: 1, y: 1, z: 1), perspective: animateIntersect ? 5 : -5)
} animation: { animateIntersect in
.easeOut(duration: 12).repeatForever(autoreverses: false)
}
PhaseAnimator([false ,true]) { animateGreenRight in
Image("green-right")
.rotationEffect(.degrees(animateGreenRight ? -300 : 360))
.hueRotation(.degrees(animateGreenRight ? 300 : -15))
.rotation3DEffect(.degrees(15), axis: (x: 1, y: animateGreenRight ? -1 : 1, z: 0), perspective: animateGreenRight ? -1 : 1)
} animation: { animateGreenRight in
.easeInOut(duration: 12).repeatForever(autoreverses: false)
}
PhaseAnimator([false ,true]) { animateGreenLeft in
Image("green-left")
.rotationEffect(.degrees(animateGreenLeft ? 360 : -360))
.hueRotation(.degrees(animateGreenLeft ? 180 :50))
.rotation3DEffect(.degrees(75), axis: (x: 1, y: animateGreenLeft ? -5 : 15, z: 0))
} animation: { animateGreenLeft in
.easeIn(duration: 12).repeatForever(autoreverses: false)
}
PhaseAnimator([false ,true]) { animateBottomPink in
Image("bottom-pink")
.rotationEffect(.degrees(animateBottomPink ? 400 : -360))
.hueRotation(.degrees(animateBottomPink ? 0 : 230))
.opacity(0.25)
.blendMode(.multiply)
.rotation3DEffect(.degrees(75), axis: (x: 5, y: animateBottomPink ? 1 : -45, z: 0))
} animation: { animateBottomPink in
.easeOut(duration: 12).repeatForever(autoreverses: false).delay(0.6)
}
PhaseAnimator([false ,true]) { animateHighlight in
Image("highlight")
.rotationEffect(.degrees(animateHighlight ? 360 : 250))
.hueRotation(.degrees(animateHighlight ? 0 : 230))
} animation: { animateHighlight in
.easeInOut(duration: 12).repeatForever(autoreverses: false)
}
}
.blendMode(.hardLight)
.scaleEffect(0.4)
}
}
#Preview {
ListeningVoiceAnimation()
.preferredColorScheme(.dark)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment