8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

【SwiftUI】美しいカラーボールアニメーションの作り方

Last updated at Posted at 2023-06-29

はじめに

この記事では、SwiftUIで美しいカラーボールアニメーションを作る方法を紹介します。

作るもの

7色のカラーボールがなめらかに動くアニメーションを作ります。

デモ

作り方

コード全体

import SwiftUI

struct AnimatedSevenGradientBallsView: View {
    private let colors: [Color]
    
    private let colorsCount: Int
    
    @State private var positions: [CGPoint]
    
    @State private var show = true
    
    init() {
        colors = [
            .red,
            .orange,
            .yellow,
            .green,
            .blue,
            .purple,
            .pink
        ]
        
        colorsCount = colors.count
        
        positions = Array(repeating: .zero, count: colorsCount)
    }
    
    var body: some View {
        ZStack {
            if show {
                ForEach(0..<colorsCount, id: \.self) { index in
                    Circle()
                        // Colorのgradientプロパティを使うと、
                        // その色のグラデーションを作れる
                        .fill(colors[index].gradient)

                        // blendModeをlightenにすると、
                        // 重なった部分が明るくなる
                        .blendMode(.lighten)

                        .frame(width: 160, height: 160)
                        .offset(x: positions[index].x, y: positions[index].y)
                        .animation(

                            // repeatForeverで繰り返しアニメーションを作れる
                            // autoreversesをtrueにすると、
                            // アニメーションが終わったら逆方向にアニメーションする
                            // delayでアニメーションの開始を遅らせることができる
                            // ここでは、indexに応じてアニメーションの開始を遅らせている
                            // そうすることで美しいアニメーションを実現している
                            .easeInOut(duration: 1).repeatForever(autoreverses: true).delay(Double(index) * 0.1),
                            value: positions
                        )
                }
            }
            
            Rectangle()

                // Materialを使うと、
                // 背後に表示されるビューにぼかしをかけられる
                .fill(Material.ultraThin)
                .ignoresSafeArea()
        }
        .preferredColorScheme(.dark) // 常にダークモードにする
        .onAppear {
            setPositions()
        }

        // iPhoneを回転させるとアニメーションが止まるバグがあるので、
        // リロードできるようにしている
        .onTapGesture {
            show.toggle()
        }
        .onChange(of: show) { show in
            if show {
                setPositions()
            } else {
                positions = Array(repeating: .zero, count: colorsCount)
            }
        }
    }
    
    private func setPositions() {
        // 角円の座標を円状に配置する(最初は全て中心にある)
        for index in 0 ..< colorsCount {
            positions[index] = CGPoint(
                x: 80 * cos(Double(index) * 2 * Double.pi / Double(colorsCount)),
                y: 80 * sin(Double(index) * 2 * Double.pi / Double(colorsCount))
            )
        }
    }
}

ポイント

  • blendModeをlightenにすると、重なった部分が明るくなる
  • repeatForeverで繰り返しアニメーションを作れる
  • autoreversesをtrueにすると、アニメーションが終わったら逆方向にアニメーションできる
  • 最初は全て中心にある角円の座標を円状に配置する(この時にアニメーションがかかる)

まとめ

SwiftUIで美しいカラーボールアニメーションを作りました。SwiftUIのテクニックが多く詰まっているので、自分でもまた見返したいと思いました👀

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?