Created
June 16, 2024 12:48
-
-
Save teameh/1cc7e4272ab6767b733738720d49f5f7 to your computer and use it in GitHub Desktop.
Animated Mesh Gradients in SwiftUI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ContentView.swift | |
// MeshGradientTests | |
// | |
// Created by Tieme van Veen on 15/06/2024. | |
// | |
import SwiftUI | |
let allColors: [Color] = [ | |
.red, .orange, .yellow, .green, | |
.mint, .teal, .cyan, .blue, .indigo, | |
.purple, .pink, .brown | |
] | |
let fourRandomColors = { (0..<4).map { _ in allColors.randomElement()! } } | |
let initialColors = fourRandomColors() | |
struct ContentView: View { | |
@State var colors: [Color] = initialColors | |
@State var meshColors: [Color] = (0..<9).map { _ in initialColors.randomElement()! } | |
@State var timer: Timer? | |
var body: some View { | |
ZStack { | |
MeshGradient ( | |
width: 3, height: 3, points: [ | |
[0.0, 0.0], [0.5, 0.0], [1.0, 0.0], | |
[0.0, 0.5], [0.5, 0.5], [1.0, 0.5], | |
[0.0, 1.0], [0.5, 1.0], [1.0, 1.0] | |
], | |
colors: meshColors | |
) | |
VStack { | |
Spacer() | |
grid | |
button | |
} | |
} | |
.edgesIgnoringSafeArea(.all) | |
.onAppear { | |
timer = Timer.scheduledTimer(withTimeInterval: 4, repeats: true, block: { timer in | |
withAnimation(.easeInOut(duration: 4)) { | |
meshColors = (0..<9).map { _ in colors.randomElement()! } | |
} | |
}) | |
} | |
} | |
var grid: some View { | |
VStack(spacing: 1) { | |
ForEach([meshColors[0..<3], meshColors[3..<6], meshColors[6..<9]], id: \.self) { colors in | |
HStack(spacing: 1) { | |
ForEach(colors, id: \.self) { color in | |
Rectangle() | |
.frame(width: 10, height: 10) | |
.foregroundColor(color) | |
.border(.white, width: 0.5) | |
} | |
} | |
} | |
} | |
.padding() | |
.transaction { $0.animation = nil } | |
} | |
var button: some View { | |
Button { | |
withAnimation(.easeInOut(duration: 0.5)) { | |
colors = fourRandomColors() | |
meshColors = (0..<9).map { _ in colors.randomElement()! } | |
} | |
} label: { | |
Text("Change colors") | |
.font(.headline) | |
.foregroundColor(.black) | |
.padding() | |
.background(.ultraThinMaterial) | |
.cornerRadius(16) | |
} | |
.padding() | |
} | |
} | |
#Preview { | |
ContentView() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment