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