Files
omnivore/apple/OmnivoreKit/Sources/Views/ShimmerView.swift
2022-05-09 16:44:02 -07:00

55 lines
1.4 KiB
Swift

import SwiftUI
public struct ShimmeringLoader: View {
@State private var phase: CGFloat = 0
public init() {}
public var body: some View {
ZStack {
Color.systemBackground
Color.appGraySolid
.contentShape(Rectangle())
.modifier(AnimatedMask(phase: phase).animation(
Animation.linear(duration: 2.0)
.repeatForever(autoreverses: false)
))
.onAppear { phase = 0.8 }
}
.frame(height: 2)
.frame(maxWidth: .infinity)
}
/// An animatable modifier to interpolate between `phase` values.
struct AnimatedMask: AnimatableModifier {
var phase: CGFloat = 0
var animatableData: CGFloat {
get { phase }
set { phase = newValue }
}
func body(content: Content) -> some View {
content
.mask(GradientMask(phase: phase).scaleEffect(3))
}
}
/// An animatable gradient between transparent and opaque to use as mask.
/// The `phase` parameter shifts the gradient, moving the opaque band.
struct GradientMask: View {
let phase: CGFloat
let centerColor = Color.appGraySolid
let edgeColor = Color.clear
var body: some View {
LinearGradient(gradient:
Gradient(stops: [
.init(color: edgeColor, location: phase),
.init(color: centerColor, location: phase + 0.1),
.init(color: edgeColor, location: phase + 0.2)
]), startPoint: .leading, endPoint: .trailing)
}
}
}