Skip to content

Instantly share code, notes, and snippets.

@ejjonny
Created March 18, 2022 19:02
Show Gist options
  • Save ejjonny/cef854b8fae1115ef7916ced6bcfde23 to your computer and use it in GitHub Desktop.
Save ejjonny/cef854b8fae1115ef7916ced6bcfde23 to your computer and use it in GitHub Desktop.
import SwiftUI
import Foundation
import Combine
struct ContentView: View {
struct ImageInfo: Identifiable {
let id = UUID()
let name: String
init(_ name: String) {
self.name = name
}
}
let images: [ImageInfo] = [
.init("image1"),
.init("image2"),
.init("image3"),
.init("image4"),
.init("image5")
]
var body: some View {
ZStack {
ForEach(images.indices, id: \.self) { i in
Image(images[i].name)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 200)
.mask {
AnimatedStripes(
stripeIndex: i,
stripeWidth: 100,
patternRepetition: 5,
patternStripeCount: images.count,
direction: .right,
shear: 0.5,
duration: 10
)
}
}
}
}
}
struct AnimatedStripes: View {
enum Direction {
case left
case right
}
@State var animate = false
let stripeIndex: Int
let stripeWidth: CGFloat
let patternRepetition: Int
let patternStripeCount: Int
let direction: Direction
let shear: CGFloat
let duration: CGFloat
var patternWidth: CGFloat {
stripeWidth * CGFloat(patternStripeCount)
}
var targetOffset: CGFloat {
direction == .right ? patternWidth : -patternWidth
}
var body: some View {
HStack(spacing: 0) {
ForEach(0..<patternRepetition, id: \.self) { _ in
Rectangle()
.frame(width: stripeWidth)
.frame(width: patternWidth)
}
}
.offset(x: stripeWidth * CGFloat(stripeIndex))
.offset(x: animate ? targetOffset : 0)
.frame(width: patternWidth)
.transformEffect(.init(a: 1, b: 0, c: shear, d: 1, tx: 0, ty: 0))
.onAppear {
withAnimation(
.linear(duration: duration)
.repeatForever(autoreverses: false)
) {
animate.toggle()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment