Created
January 24, 2025 16:21
-
-
Save LidorFadida/af1f5a0a1ce183490e342c0e600f803d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // Depth-Illusion-Example | |
| // | |
| // Created by Lidor Fadida on 24/01/2025. | |
| // | |
| import SwiftUI | |
| //MARK: - Circle Configuration | |
| struct CircleConfiguration: Identifiable, Hashable { | |
| let id: UUID | |
| let color: Color | |
| init(id: UUID = UUID(), color: Color = .black) { | |
| self.id = id | |
| self.color = color | |
| } | |
| } | |
| //MARK: - Column Configuration Protocol | |
| protocol ColumnsViewConfigurationProtocol { | |
| var circles: [CircleConfiguration] { get } | |
| var offset: CGFloat { get } | |
| var delay: TimeInterval { get } | |
| } | |
| //MARK: - Column Configuration | |
| struct ColumnsViewConfiguration: ColumnsViewConfigurationProtocol { | |
| let circles: [CircleConfiguration] | |
| let offset: CGFloat | |
| let delay: TimeInterval | |
| } | |
| //MARK: - A Column | |
| struct ColumnsView<Configuration: ColumnsViewConfigurationProtocol>: View { | |
| @State private var animate: Bool = false | |
| let configuration: Configuration | |
| var body: some View { | |
| let circles = configuration.circles | |
| let offset = configuration.offset | |
| ZStack { | |
| ForEach(Array(circles.enumerated()), id: \.element) { index, circle in | |
| let width: Double = 5 + (0.4 * Double(circles.count - index)) | |
| Circle() | |
| .fill(circle.color.gradient) | |
| .frame(width: width) | |
| .offset(y: animate ? -offset : offset) | |
| .animation( | |
| .easeInOut(duration: 3.0) | |
| .repeatForever(autoreverses: true) | |
| .delay(0.1 * Double(index)), | |
| value: animate | |
| ) | |
| } | |
| } | |
| .task { | |
| try? await Task.sleep(for: .seconds(configuration.delay)) | |
| animate.toggle() | |
| } | |
| } | |
| } | |
| //MARK: - Example Constants | |
| let numberOfColumns: Int = 30 | |
| let colors: [Color] = [.white, .blue, .yellow/* Insert your colors here*/] | |
| let itemsPerColumn = (0..<numberOfColumns).map { i in CircleConfiguration(color: colors[i % colors.count]) } | |
| let inset = 24.0 | |
| //MARK: - The Example. | |
| struct PreviewExample: View { | |
| let offset: ((Int) -> CGFloat) | |
| let delay: ((Int) -> TimeInterval) | |
| var body: some View { | |
| HStack(spacing: 5.0) { | |
| ForEach(0..<numberOfColumns, id: \.self) { i in | |
| let configuration = ColumnsViewConfiguration( | |
| circles: itemsPerColumn, | |
| offset: offset(i), | |
| delay: delay(i) | |
| ) | |
| ColumnsView(configuration: configuration) | |
| } | |
| } | |
| } | |
| } | |
| #Preview("Wall") { | |
| GeometryReader { proxy in | |
| let size = proxy.size | |
| PreviewExample { _ in | |
| return min(size.width / 2.0, size.height / 2.0) - inset | |
| } delay: { index in | |
| return 0.0 | |
| } | |
| .frame(width: proxy.size.width, height: proxy.size.height) | |
| } | |
| .background(Color.black, ignoresSafeAreaEdges: .all) | |
| } | |
| #Preview("Wave") { | |
| GeometryReader { proxy in | |
| let size = proxy.size | |
| PreviewExample { _ in | |
| return min(size.width / 2.0, size.height / 2.0) - inset | |
| } delay: { index in | |
| return 0.1 * Double(index) | |
| } | |
| .frame(width: proxy.size.width, height: proxy.size.height) | |
| } | |
| .background(Color.black, ignoresSafeAreaEdges: .all) | |
| } | |
| #Preview("Cone") { | |
| GeometryReader { proxy in | |
| let size = proxy.size | |
| PreviewExample { index in | |
| let maximumOffset = min(size.width / 2.0, size.height / 2.0) - inset | |
| let offset = maximumOffset - (5.0 * Double(index)) | |
| return offset | |
| } delay: { index in | |
| return 0.1 * Double(index) | |
| } | |
| .frame(width: proxy.size.width, height: proxy.size.height) | |
| .rotationEffect(.degrees(90)) | |
| } | |
| .background(Color.black, ignoresSafeAreaEdges: .all) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment