畫面有了~功能也有了~
接下來我們做個小動畫
我們試著讓小雞在畫面中跳起來
整個APP 感覺就活起來了
關於動畫~swift也不少方法都可以跑動畫
這邊我們採用影格動畫來玩看看
讓我們來看一下語法
UIView.animateKeyframes(
withDuration: 動畫執行秒數,
delay: 延期秒數,
options: [.動畫參數],
animations: {
在這裡設定動畫影格
},
completion: {
完成後要做的事情
}
)
語法上看起來不難對吧~
那我們來想一下小雞要怎麼動吧~
我們來做個小雞左右跳動的效果好了
左右跳動需要變更到以下屬性
屬性名稱 | 說明 |
---|---|
translationX | 透過改變x座標值, 讓小雞呈現左右移動的效果 |
rotated | 透過變更角度, 讓小雞有種往上跳起, 與往下降落的感覺 |
centerY | 利用改變中心Y軸, 來實現上下跳動的感覺, 其實也可以用translationY, 這邊是為了示範而用centerY |
scaledX | 當小雞跳到最左與最右時, 翻轉小雞, 小雞維持往前的效果, 如果沒有翻轉會看到小雞倒車跑 |
只需要這幾個屬性~就可以讓小雞動起來摟 | |
animateKeyframes 只要我們設定每個關鍵時間點的屬性 | |
接下來他就會幫我們把中間的數值補起來摟 | |
讓我們來規劃一下動畫時間軸 | |
為了不要讓時間被寫死, 我們用佔時百分比顯示 | |
時間(用百分比表示) | 說明 |
----- | -------- |
0% => 10% | 小雞往左邊跳起 |
10% => 20% | 小雞往左邊降下 |
20% => 30% | 小雞往左邊跳起 |
30% => 40% | 小雞轉身往右邊降下迴轉 |
40% => 50% | 小雞往右邊跳起 |
50% => 60% | 小雞往右邊降下跳回原點 |
60% => 70% | 小雞往右邊跳起 |
70% => 80% | 小雞往右邊降下迴轉 |
80% => 90% | 小雞轉身往左邊跳起 |
90% => 100% | 小雞往左邊落下回原點 |
目前用這樣的思維來讓小雞左右跳動吧 | |
接著我們看看關鍵影格的語法 |
UIView.addKeyframe(
withRelativeStartTime: 動畫開始百分比,
relativeDuration: 動畫播放時間百分比,
animations: {
要變更的動畫屬性
}
)
好摟~那我們來建立個資料模型吧
struct KeyFrameOptionItem {
let startTime: Double // 動畫開始時間
let translationX: CGFloat // 左右位移
let centerY: Double // 上下跳動
let rotated: CGFloat // 上下角度
let scaledX: CGFloat // 水平翻轉
init(startTime: Double, translationX: CGFloat, centerY: Double, rotated: CGFloat, scaledX: CGFloat) {
let oneDegree = CGFloat.pi / 180 // 透過pi轉換rotated角度
self.startTime = startTime
self.translationX = translationX
self.rotated = rotated * oneDegree
self.centerY = centerY
self.scaledX = scaledX
}
}
資料模型完成後
讓我們把動畫的參數都建立出來吧
var keyFrameOptions: Array<KeyFrameOptionItem> = []
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.0, translationX: -33.0, centerY: 328.0, rotated: 10, scaledX: 1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.1, translationX: -66.0, centerY: 348.0, rotated: -10, scaledX: 1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.2, translationX: -99.0, centerY: 348.0, rotated: 10, scaledX: 1.0))
// 以上向左邊跳到底後轉身往回走
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.3, translationX: -66.0, centerY: 348.0, rotated: -10, scaledX: -1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.4, translationX: -33.0, centerY: 348.0, rotated: 10, scaledX: -1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.5, translationX: 0.0, centerY: 348.0, rotated: -10, scaledX: -1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.6, translationX: 40.0, centerY: 348.0, rotated: 10, scaledX: -1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.7, translationX: 100.0, centerY: 348.0, rotated: -10, scaledX: -1.0))
//跳到最右邊後 轉身往原點走
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.8, translationX: 40.0, centerY: 348.0, rotated: 10, scaledX: 1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.9, translationX: 0.0, centerY: 348.0, rotated: -10, scaledX: 1.0))
接下來就設定repeat屬性與用for迴圈設定影格吧
UIView.animateKeyframes(
withDuration: 4,
delay: 0.0,
options: [.repeat],
animations: {
for option in keyFrameOptions {
UIView.addKeyframe(
withRelativeStartTime: option.startTime,
relativeDuration: 0.1,
animations: {
self.ggImg.transform = CGAffineTransform(translationX: option.translationX, y: 0.0)
.rotated(by: option.rotated)
.scaledBy(x: option.scaledX, y: 1.0)
self.ggImg.center = CGPoint(x: 207.0, y: option.centerY)
}
)
}
},
completion: nil
)
好摟~通過以上設定
只要執行後 左右跳動的動畫就會不斷循環
跳起來~
讓我們看一下完整的程式碼
import UIKit
struct KeyFrameOptionItem {
let startTime: Double // 動畫開始時間
let translationX: CGFloat // 左右位移
let centerY: Double // 上下跳動
let rotated: CGFloat // 上下角度
let scaledX: CGFloat // 水平翻轉
init(startTime: Double, translationX: CGFloat, centerY: Double, rotated: CGFloat, scaledX: CGFloat) {
let oneDegree = CGFloat.pi / 180 // 透過pi轉換rotated角度
self.startTime = startTime
self.translationX = translationX
self.rotated = rotated * oneDegree
self.centerY = centerY
self.scaledX = scaledX
}
}
class ViewController: UIViewController {
// BB~ Label的UI元件參照
@IBOutlet weak var ggVoice: UILabel!
//小雞 圖片 參照
@IBOutlet weak var ggImg: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setChickAnimation()
}
// 小雞BB~ Button 被點擊時, 會執行的方法
@IBAction func ggAction(_ sender: UIButton) {
ggVoice.text?.append("BB~")
}
func setChickAnimation() {
var keyFrameOptions: Array<KeyFrameOptionItem> = []
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.0, translationX: -33.0, centerY: 328.0, rotated: 10, scaledX: 1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.1, translationX: -66.0, centerY: 348.0, rotated: -10, scaledX: 1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.2, translationX: -99.0, centerY: 348.0, rotated: 10, scaledX: 1.0))
// 以上向左邊跳到底後轉身往回走
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.3, translationX: -66.0, centerY: 348.0, rotated: -10, scaledX: -1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.4, translationX: -33.0, centerY: 348.0, rotated: 10, scaledX: -1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.5, translationX: 0.0, centerY: 348.0, rotated: -10, scaledX: -1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.6, translationX: 40.0, centerY: 348.0, rotated: 10, scaledX: -1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.7, translationX: 100.0, centerY: 348.0, rotated: -10, scaledX: -1.0))
//跳到最右邊後 轉身往原點走
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.8, translationX: 40.0, centerY: 348.0, rotated: 10, scaledX: 1.0))
keyFrameOptions.append(KeyFrameOptionItem(startTime: 0.9, translationX: 0.0, centerY: 348.0, rotated: -10, scaledX: 1.0))
UIView.animateKeyframes(
withDuration: 4,
delay: 0.0,
options: [.repeat],
animations: {
for option in keyFrameOptions {
UIView.addKeyframe(
withRelativeStartTime: option.startTime,
relativeDuration: 0.1,
animations: {
self.ggImg.transform = CGAffineTransform(translationX: option.translationX, y: 0.0)
.rotated(by: option.rotated)
.scaledBy(x: option.scaledX, y: 1.0)
self.ggImg.center = CGPoint(x: 207.0, y: option.centerY)
}
)
}
},
completion: nil
)
}
}
此時只要APP運行
在 viewDidLoad , 就會不斷播放這則動畫了
動起來了!
在做網頁的時候, 只要能讓畫面動起來
整個就大加分~
看到自己畫的小雞跳起來
超級爽Der
真好奇同樣的動畫在Android
會用怎麼樣的寫法
動畫的內容比較多
明天再來一起看看Kotlin的寫法吧