首先普及一下iOS開發(fā)中的動畫矩陣變換
大家知道, UIView中的transform表示的是2D的矩陣,而CALayer中卻是3D矩陣,它包含了3D變換。
? 在UIView里面的transform已經(jīng)在Apple官方SDK文檔里面有詳細的介紹,而且框架也提供了詳細的變換方法。在3D的方式下大部分情況與2D相同,主要是旋轉(zhuǎn)變換, 需要較強的空間思維能力。變換方法原型: CATransform3D, 其中進行三維翻轉(zhuǎn)的函數(shù):CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z); 第一個參數(shù)是旋轉(zhuǎn)角度,后面三個參數(shù)形成一個圍繞其旋轉(zhuǎn)的向量,起點位置由UIView的center屬性標識。
? 在這里需要說明的是在3D變換的時候,如果是變換的向量和屏幕垂直(z軸),那么就會相當于2D的旋轉(zhuǎn)變化。如果不是垂直的,系統(tǒng)會現(xiàn)將整個畫面調(diào)整到與這個向量垂直(沒有動畫),再進行旋轉(zhuǎn)。所以會形成一個跳躍,破壞動畫的連貫。
? 所以如果有這類變換的情況建議考慮動畫的連貫性(體驗!),先將view動畫變換到和向量垂直,然后進行旋轉(zhuǎn),最后再恢復和屏幕平行。
使用CATransform3DMakeRotation實現(xiàn)小米運動首頁效果
Swift極大提高了效率, 這個小Demo代碼不超過200行, 感興趣的小伙伴可移步MIDemo
- 效果可參考如下:
MI-HomePage-Animation.gif
? 主要使用CATransform3DMakeRotation函數(shù)進行3D矩陣變換, 實質(zhì)上將一張平面圖通過繞其X軸進行角度偏轉(zhuǎn), 偏轉(zhuǎn)的角度由上拉的距離經(jīng)定值特殊計算而來
let offsetH : CGFloat = 406.0; // 頭部高度
if ((offsetH - slideH)/210) > 0 { // 判斷是否上推, slideH是滑動距離
dataImageView.layer.transform = CATransform3DMakeRotation(((offsetH - slideH) / 210) * CGFloat(M_PI_2), 0.3, 0, 0)
}
以下是小三角往復旋轉(zhuǎn)的實現(xiàn), 同樣使用UIView的CGAffineTransform函數(shù)進行三維矩陣變換
if isSlideMax { // 如果向下滑動距離到臨界值
tipsLabel.text = "松手開始同步"
UIView.animate(withDuration: 0.3, animations: {
self.tipsImageView.transform = CGAffineTransform.init(rotationAngle:CGFloat(NSNumber(value: M_PI)))
})
} else {
tipsLabel.text = "下拉同步數(shù)據(jù)"
UIView.animate(withDuration: 0.3, animations: {
self.tipsImageView.transform = CGAffineTransform.init(rotationAngle: CGFloat(NSNumber(value: M_PI * 2)))
})
}
