Contents

ganeshsarmak/animatedcarousel

A SwiftUI package providing beautiful, animated layouts for collections of views. Choose from 7 built-in layout styles including circular, spiral, grid, radial, wave, helix, and custom arrangements.

✨ Features

  • 🎯 7 Layout Styles: Circular, Spiral, Grid, Radial, Wave, Helix, Custom
  • 🎨 Dynamic Parameters: Adjust grid columns, radial arcs, wave orientation, helix strands
  • 🌊 Smooth Animations: Spring-based animations with configurable timing
  • πŸŽ›οΈ Highly Customizable: Control spacing, size, animation curves, and more
  • πŸ“± Cross-Platform: Works on iOS 15+ and macOS 12+
  • πŸ§ͺ Well-Tested: Comprehensive unit tests for all layouts
  • πŸš€ Zero Dependencies: Pure SwiftUI implementation

πŸ“¦ Installation

Swift Package Manager

Add AnimatedCarousel to your project via Xcode:

  1. File β†’ Add Package Dependencies
  2. Enter package URL: https://github.com/ganeshsarmak/AnimatedCarousel
  3. Select version and add to your target

Or add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/ganeshsarmak/AnimatedCarousel", from: "1.0.0")
]

🎬 Quick Start

import SwiftUI
import AnimatedCarousel

struct MyView: View {
    @State private var visibleCount = 0
    let items = ["🌟", "🎨", "πŸš€", "🎸", "πŸ€", "🎭", "πŸ“š", "🎡"]
    
    var body: some View {
        VStack {
            AnimatedCarousel(
                data: items.enumerated().map { Item(id: $0, value: $1) },
                visibleCount: $visibleCount,  // Use binding!
                style: .circular,
                itemSize: 60,
                spacing: 100,
                autoAdvance: true,            // Enable auto-advance!
                autoAdvanceInterval: 0.5      // Advance every 0.5 seconds
            ) { item in
                Text(item.value)
                    .font(.system(size: 40))
                    .frame(width: 60, height: 60)
                    .background(Color.blue.opacity(0.3))
                    .clipShape(Circle())
            }
            
            Button("Add Item") {
                if visibleCount < items.count {
                    visibleCount += 1
                }
            }
        }
    }
}

struct Item: Identifiable {
    let id: Int
    let value: String
}

🎨 Layout Styles

Circular

Items arranged in a perfect circle around the center.

AnimatedCarousel(data: items, visibleCount: $count, style: .circular)

Spiral

Items arranged in an expanding spiral pattern.

AnimatedCarousel(data: items, visibleCount: count, style: .spiral)

Grid

Traditional grid layout with adjustable columns.

AnimatedCarousel(
    data: items,
    visibleCount: count,
    style: .grid,
    gridConfig: GridConfiguration(columns: 4)
)

Radial

Fan-like arrangement with adjustable arc angle (45Β° to 360Β°).

AnimatedCarousel(
    data: items,
    visibleCount: count,
    style: .radial,
    radialConfig: RadialConfiguration(arcAngle: 180)
)

Wave

Sine wave pattern, horizontal or vertical.

AnimatedCarousel(
    data: items,
    visibleCount: count,
    style: .wave,
    waveConfig: WaveConfiguration(isVertical: false)
)

Helix

3D helix effect with 1-4 configurable strands.

AnimatedCarousel(
    data: items,
    visibleCount: count,
    style: .helix,
    helixConfig: HelixConfiguration(strands: 2)  // Double helix
)

Custom

Diagonal line arrangement (modify for your own custom positions).

AnimatedCarousel(data: items, visibleCount: $count, style: .custom)

⏱️ Auto-Advance

Enable automatic advancement through items - perfect for galleries, demos, and presentations!

Basic Auto-Advance

AnimatedCarousel(
    data: items,
    visibleCount: $count,
    style: .spiral,
    autoAdvance: true,
    autoAdvanceInterval: 0.5  // Advance every 0.5 seconds
)

Auto-Advance with Looping

AnimatedCarousel(
    data: items,
    visibleCount: $count,
    style: .circular,
    autoAdvance: true,
    autoAdvanceInterval: 1.0,
    autoAdvanceLoop: true  // Loop back to start when reaching end
)

Toggle Auto-Advance

struct GalleryView: View {
    @State private var count = 0
    @State private var isPlaying = false
    
    var body: some View {
        VStack {
            AnimatedCarousel(
                data: photos,
                visibleCount: $count,
                style: .radial,
                autoAdvance: isPlaying,
                autoAdvanceInterval: 1.5
            ) { photo in
                PhotoView(photo)
            }
            
            Button(isPlaying ? "Pause" : "Play") {
                isPlaying.toggle()
            }
        }
    }
}

βš™οΈ Customization

Animation Configuration

AnimatedCarousel(
    data: items,
    visibleCount: count,
    style: .spiral,
    staggerDelay: 0.1,        // Delay between items
    springResponse: 0.4,       // Spring stiffness
    springDamping: 0.6         // Spring damping
)

Layout Parameters

Grid:

gridConfig: GridConfiguration(columns: 5)  // 2-8 columns

Radial:

radialConfig: RadialConfiguration(arcAngle: 270)  // 45-360 degrees

Wave:

waveConfig: WaveConfiguration(
    isVertical: true,
    frequency: 0.5,
    amplitude: 80
)

Helix:

helixConfig: HelixConfiguration(strands: 3)  // 1-4 strands

πŸ“± Example App

Check out the included example app in Examples/ImageAnimation for interactive demonstrations of all layouts and parameters.

πŸ§ͺ Testing

Run tests with:

swift test

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

🀝 Contributing

Contributions are welcome! Feel free to open issues or submit pull requests.

πŸ‘€ Author

Created by NVR4GET

⭐ Show Your Support

If you find this package useful, please consider giving it a star on GitHub!

Package Metadata

Repository: ganeshsarmak/animatedcarousel

Default branch: main

README: README.md