mirror of https://github.com/lukechilds/damus.git
Sam DuBois
2 years ago
3 changed files with 81 additions and 9 deletions
@ -0,0 +1,77 @@ |
|||||
|
// |
||||
|
// Shimmer.swift |
||||
|
// |
||||
|
// |
||||
|
// Created by Joshua Homann on 2/20/21. |
||||
|
// |
||||
|
|
||||
|
import SwiftUI |
||||
|
|
||||
|
public struct ShimmerConfiguration { |
||||
|
|
||||
|
@Environment(\.colorScheme) var colorScheme |
||||
|
|
||||
|
public let gradient: Gradient |
||||
|
public let initialLocation: (start: UnitPoint, end: UnitPoint) |
||||
|
public let finalLocation: (start: UnitPoint, end: UnitPoint) |
||||
|
public let duration: TimeInterval |
||||
|
public let opacity: Double |
||||
|
public static let `default` = ShimmerConfiguration( |
||||
|
gradient: Gradient(stops: [ |
||||
|
.init(color: .clear, location: 0), |
||||
|
.init(color: .black, location: 0.3), |
||||
|
.init(color: .black, location: 0.7), |
||||
|
.init(color: .clear, location: 1), |
||||
|
]), |
||||
|
initialLocation: (start: UnitPoint(x: -1, y: 0.5), end: .leading), |
||||
|
finalLocation: (start: .trailing, end: UnitPoint(x: 2, y: 0.5)), |
||||
|
duration: 2, |
||||
|
opacity: 0.6 |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
struct ShimmeringView<Content: View>: View { |
||||
|
private let content: () -> Content |
||||
|
private let configuration: ShimmerConfiguration |
||||
|
@State private var startPoint: UnitPoint |
||||
|
@State private var endPoint: UnitPoint |
||||
|
init(configuration: ShimmerConfiguration, @ViewBuilder content: @escaping () -> Content) { |
||||
|
self.configuration = configuration |
||||
|
self.content = content |
||||
|
_startPoint = .init(wrappedValue: configuration.initialLocation.start) |
||||
|
_endPoint = .init(wrappedValue: configuration.initialLocation.end) |
||||
|
} |
||||
|
var body: some View { |
||||
|
ZStack { |
||||
|
content() |
||||
|
LinearGradient( |
||||
|
gradient: configuration.gradient, |
||||
|
startPoint: startPoint, |
||||
|
endPoint: endPoint |
||||
|
) |
||||
|
.opacity(configuration.opacity) |
||||
|
.blendMode(.overlay) |
||||
|
.onAppear { |
||||
|
withAnimation(Animation.linear(duration: configuration.duration).repeatForever(autoreverses: false)) { |
||||
|
startPoint = configuration.finalLocation.start |
||||
|
endPoint = configuration.finalLocation.end |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.edgesIgnoringSafeArea(.all) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public struct ShimmerModifier: ViewModifier { |
||||
|
let configuration: ShimmerConfiguration |
||||
|
public func body(content: Content) -> some View { |
||||
|
ShimmeringView(configuration: configuration) { content } |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public extension View { |
||||
|
func shimmer(configuration: ShimmerConfiguration = .default) -> some View { |
||||
|
modifier(ShimmerModifier(configuration: configuration)) |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue