以前、このような物理法則っぽいLoadingのアニメーションを作成しました。
これでは、AnimationにtimingCurveを使って、アニメーションに緩急をつけています。
timingCurveのドキュメント
解説
まず、もっと簡単な場合を考えてみましょう。
struct ProgressCircleExplain: View {
@State private var animate = false
var body: some View {
ZStack {
Circle() // Outer circle
.frame(width: 250, height: 250)
.foregroundColor(.gray)
.opacity(0)
Circle() // Single Moving circle
.frame(width: 20, height: 20)
.foregroundColor(Color.blue)
.offset(y: 50) // Set the radius of the outer circle here
.rotationEffect(.degrees(self.animate ? 360 : 0))
.animation(
Animation
.timingCurve(0.1, 0.7, 0.9, 0.2, duration: 1.9)
.repeatForever(autoreverses: false)
)
.onAppear() {
self.animate = true
}
}
}
}
これは、一個の円が円を描いて開店するアニメーションのコードです。
等速で円周上を回転していますね。
これに、緩急をつけることで滑り落ちるようなアニメーションにします。
timingCurve はアニメーションに割り当てられる時間を、調整することができます。
実際に先ほどのコードにtimingCurveを適応したものを実装してみましょう。
struct ProgressCircleExplain: View {
@State private var animate = false
var body: some View {
ZStack {
Circle() // Outer circle
.frame(width: 250, height: 250)
.foregroundColor(.gray)
.opacity(0)
Circle() // Single Moving circle
.frame(width: 20, height: 20)
.foregroundColor(Color.blue)
.offset(y: 50) // Set the radius of the outer circle here
.rotationEffect(.degrees(self.animate ? 360 : 0))
.animation(
Animation
.timingCurve(0.1, 0.7, 0.9, 0.2, duration: 1.9)
.repeatForever(autoreverses: false)
)
.onAppear() {
self.animate = true
}
}
}
}
これを動かすと以下のようになります。
今回のアニメーションは以下のように図示することができます。
今回のアニメーションの円運動は、0~360°まで変異させることで、円周上を移動するアニメーションを実装しています。
滑り落ちる挙動にしたければ、降っている状態では、時間の進みが早く、上りの時に遅くなるようにすればそれに近づけれます。
そこで使用するのがtimingCurveです。
timingCurveはアニメーションを分割し、それらにかかる時間を調整することが可能です。
今回は
.timingCurve(0.1, 0.7, 0.9, 0.2, duration: 1.9)
を使用しています。これは
0~90°は0.1秒で処理をする。
90~180°は0.7秒で処理をする。
180~270°は0.9秒で処理をする。
270~360°は0.2秒で処理をする。
という表現になります。
図解するとこのようになります。
時間の総和はDurationと一致するようにしないと、アニメーションを行うたびにずれてしまうため、注意しましょう。
まとめ
このような自然法則っぽいアニメーションは実装が難しそうですが、timingCurveを使うことで簡単に再現することができました。
これでおしゃれなアニメーションを作ってみてくださいね
いいね、ブックマーク、フォローしていただけると勉強の励みになりますので是非お願いします。😉
追伸 --
Twitterで日々の学習風景を投稿してます。