Skip to content

Instantly share code, notes, and snippets.

@Erica-Iris
Forked from 1998code/ContentView.swift
Created March 1, 2025 12:04
Show Gist options
  • Save Erica-Iris/2ba239f9aa55808c02dbc2f342173c13 to your computer and use it in GitHub Desktop.
Save Erica-Iris/2ba239f9aa55808c02dbc2f342173c13 to your computer and use it in GitHub Desktop.
Shimmer Effect 2025
// Copyright © 2025 MING
// MIT License
import SwiftUI
struct ContentView: View {
@State private var colorful: Bool = true
@State private var dragLocation: CGPoint = .zero
var body: some View {
ZStack {
Color.black.edgesIgnoringSafeArea(.all)
Text("Shimmer Effect \non \(Text("SwiftUI").foregroundColor(.white))")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
.opacity(dragLocation == .zero ? 1 : 0.1)
DotGrid(colorful: $colorful, dragLocation: $dragLocation)
.background(.gray.opacity(0.1))
.cornerRadius(36)
.padding()
.gesture(
DragGesture()
.onChanged { value in
withAnimation {
dragLocation = value.location
}
}
.onEnded { _ in
withAnimation {
dragLocation = .zero
}
}
)
}
}
}
struct DotGrid: View {
@Binding var colorful: Bool
@Binding var dragLocation: CGPoint
let rows = 25
let columns = 25
let dotSize: CGFloat = 5
var body: some View {
GeometryReader { geometry in
let spacingX = (geometry.size.width - (CGFloat(columns) * dotSize)) / CGFloat(columns + 1)
let spacingY = (geometry.size.height - (CGFloat(rows) * dotSize)) / CGFloat(rows + 1)
let dots = (0..<rows).flatMap { row in
(0..<columns).map { col in
CGPoint(x: spacingX + CGFloat(col) * (dotSize + spacingX) + dotSize / 2,
y: spacingY + CGFloat(row) * (dotSize + spacingY) + dotSize / 2)
}
}
ForEach(dots, id: \.self) { dot in
Circle()
.fill(colorForDotCenter(at: dot))
.frame(width: dotSize, height: dotSize)
.position(dot)
.shadow(
color: colorForDot(at: dot),
radius: 3
)
}
}
}
private func colorForDot(at dot: CGPoint) -> Color {
guard dragLocation != .zero else { return Color.clear }
let distance = hypot(dot.x - dragLocation.x, dot.y - dragLocation.y)
let maxDistance: CGFloat = 250
let opacity = max(0, 1 - (distance / maxDistance))
return Color.white.opacity(opacity)
}
private func colorForDotCenter(at dot: CGPoint) -> Color {
guard dragLocation != .zero else { return Color.gray.opacity(0.15) }
let distance = hypot(dot.x - dragLocation.x, dot.y - dragLocation.y)
let maxDistance: CGFloat = 250
let opacity = max(0.05, 1 - (distance / maxDistance))
return colorful ? Color(
red: Double.random(in: 0...1),
green: Double.random(in: 0...1),
blue: Double.random(in: 0...1)
).opacity(opacity)
: Color.blue.opacity(opacity)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment