I would like to make an animation like Shazam's Button but I can't manage to do it...
Anyone have an idea how to make this animation in SwiftUI?
Here is the code :
import SwiftUI
import Foundation
struct SpeechButton: View {
@State var isPressed:Bool = false
var body: some View {
Button(action:{
}){
ZStack {
//--> // if self.isPressed { RoundAnimation() }
Image(systemName: "waveform")// Button Image
.resizable()
.frame(width: 40, height: 40)
.foregroundColor(.white)
}
)
}
}
Thanks in advance for your help people :)
After your code update even has more issue with it, it was not runnable, how ever you just gave me an Empty Button to work on it!
Here I got some thing for you:
import SwiftUI
struct ContentView: View {
@State var startAnimation: Bool = false
@State var random: CGFloat = 0
var timer = Timer.publish (every: 0.1, on: .main, in: .common).autoconnect()
var body: some View {
Button(action: {
// your logic!
}){
ZStack
{
Circle()
.fill(Color(UIColor.systemTeal))
Image(systemName: "waveform")
.resizable()
.frame(width: 100, height: 100)
}
.frame(width: 200, height: 200)
.scaleEffect(startAnimation ? CGFloat(1*random) : 1 )
.animation(.easeInOut)
.onTapGesture {
startAnimation.toggle()
if startAnimation == false
{
timer.upstream.connect().cancel()
}
}
}
.onReceive(timer) { _ in
random = CGFloat.random(in: 0.5...1)
}
}
}
Update Code: Version 2.0.0
import SwiftUI
struct ContentView: View {
@State var startAnimation: Bool = false
@State var random: CGFloat = 0
@State var timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
func stopTimer() {
timer.upstream.connect().cancel()
}
func startTimer() {
timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
}
var body: some View {
Button(action: {
// your logic!
}){
ZStack
{
Circle()
.fill(RadialGradient(gradient: Gradient(colors: [Color(UIColor.systemTeal), Color.white.opacity(0.1)]), center: .center, startRadius: 0, endRadius: 180))
Image(systemName: "waveform")
.resizable()
.frame(width: 100, height: 100)
}
.frame(width: 200, height: 200)
.scaleEffect(startAnimation ? random : 1 )
.animation(.easeInOut)
.onTapGesture {
startAnimation.toggle()
if startAnimation == false
{
stopTimer()
}
else
{
startTimer()
}
}
}
.onReceive(timer) { _ in
random = CGFloat.random(in: 0.5...1)
}
.onAppear()
{
stopTimer()
}
}
}
Update Code: Version 3.0.0 Much more and better Animation
import SwiftUI
struct ContentView: View {
@State var startAnimation: Bool = false
@State var random1: CGFloat = 0.5
@State var random2: CGFloat = 0.5
@State var timer = Timer.publish(every: 0.3, on: .main, in: .common).autoconnect()
func stopTimer() {
timer.upstream.connect().cancel()
}
func startTimer() {
timer = Timer.publish(every: 0.3, on: .main, in: .common).autoconnect()
}
var body: some View {
Button(action: {
// your logic!
}){
ZStack
{
Circle()
.fill(RadialGradient(gradient: Gradient(colors: [Color(UIColor.systemTeal), Color.white.opacity(0.1)]), center: .center, startRadius: 0, endRadius: 400))
.frame(width: random2*500, height: random2*500)
Circle()
.fill(RadialGradient(gradient: Gradient(colors: [Color(UIColor.gray), Color.white.opacity(0.01)]), center: .center, startRadius: 0, endRadius: 400))
.frame(width: random1*400, height: random1*400)
Circle()
.fill(RadialGradient(gradient: Gradient(colors: [Color(UIColor.systemTeal), Color.white.opacity(0.1)]), center: .center, startRadius: 150, endRadius: 190))
.frame(width: 200, height: 200)
Image(systemName: "waveform")
.resizable()
.frame(width: 100, height: 100)
}
.scaleEffect(startAnimation ? random1 : 1 )
.animation(.easeInOut)
.onTapGesture {
startAnimation.toggle()
if startAnimation == false
{
stopTimer()
}
else
{
startTimer()
}
}
}
.onReceive(timer) { _ in
random1 = CGFloat.random(in: 0.5...1)
random2 = CGFloat.random(in: 0.5...1)
print(random1, random2)
}
.onAppear()
{
stopTimer()
}
}
}