在我們創(chuàng)建想要的形狀之后,我們可以將這些屬性設(shè)置為 stroke color, ?ll color 和stroke dash pattern爹橱。
我們可以對(duì)這些屬性進(jìn)行動(dòng)畫(huà):
? path: 漸變 layer 的形狀為其它樣子萨螺。
? fillColor: 將 shape 的填充色改為不同的顏色。
? lineDashPhase: 在你的形狀周?chē)鷦?chuàng)建一個(gè) marquee 或 “marching ants” 效果
? lineWidth: 增加或縮小你的線條的線條尺寸。
現(xiàn)在我們實(shí)現(xiàn)一個(gè)小例子慰技,例子最后效果是這樣的:
代碼實(shí)現(xiàn)
avatar view
? photoLayer: avatar image layer
? circleLayer: 畫(huà)圓 layer
? maskLayer: mask layer
? label: player’s name label
bounce-off animation
bounce-off animation
func searchForOpponent() {
let avatarSize = myAvatar.frame.size
let bounceXOffset: CGFloat = avatarSize.width/1.9
let morphSize = CGSize(
width: avatarSize.width * 0.85,
height: avatarSize.height * 1.1)
let rightBouncePoint = CGPoint(
x: view.frame.size.width/2.0 + bounceXOffset,
y: myAvatar.center.y)
let leftBouncePoint = CGPoint(
x: view.frame.size.width/2.0 - bounceXOffset,
y: myAvatar.center.y)
myAvatar.bounceOff(point: rightBouncePoint, morphSize: morphSize)
opponentAvatar.bounceOff(point: leftBouncePoint, morphSize: morphSize)
delay(seconds: 4.0, completion: foundOpponent)
}
func foundOpponent() {
status.text = "Connecting..."
opponentAvatar.image = UIImage(named: "avatar-2")
opponentAvatar.name = "Ray"
delay(seconds: 4.0, completion: connectedToOpponent)
}
func connectedToOpponent() {
myAvatar.shouldTransitionToFinishedState = true
opponentAvatar.shouldTransitionToFinishedState = true
delay(seconds: 1.0, completion: completed)
}
func completed() {
status.text = "Ready to play"
UIView.animate(withDuration: 0.2) {
self.vs.alpha = 1.0
self.searchAgain.alpha = 1.0
}
}
Morphing shapes 形狀漸變
當(dāng)兩個(gè) avatars 相撞時(shí)椭盏,它們應(yīng)該在這個(gè)完全彈性碰撞中稍微擠壓一下。視圖控制器將通過(guò)一個(gè) morph size惹盼,使頭像形狀變得稍高和稍窄的效果庸汗,如圖所示:
Morphing shapes
這樣,當(dāng)他們?cè)谄聊恢虚g相遇時(shí)手报,看起來(lái)頭像互相擠壓蚯舱。
核心代碼:
func bounceOff(point: CGPoint, morphSize: CGSize) {
let originalCenter = center
UIView.animate(withDuration: animationDuration, delay: 0.0,
usingSpringWithDamping: 0.8, initialSpringVelocity: 0.0,
animations: {
self.center = point
}, completion: { _ in
//complete bounce to
if self.shouldTransitionToFinishedState {
self.animateToSquare()
}
})
UIView.animate(withDuration: animationDuration,
delay: animationDuration,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 1.0,
animations: {
self.center = originalCenter
}, completion: { _ in
delay(seconds: 0.1) {
if !self.isSquare {
self.bounceOff(point: point, morphSize: morphSize)
}
}
})
let morphedFrame = (originalCenter.x > point.x) ?
CGRect(x: 0.0, y: bounds.height - morphSize.height,
width: morphSize.width, height: morphSize.height):
CGRect(x: bounds.width - morphSize.width,
y: bounds.height - morphSize.height,
width: morphSize.width, height: morphSize.height)
let morphAnimation = CABasicAnimation(keyPath: "path")
morphAnimation.duration = animationDuration
morphAnimation.toValue = UIBezierPath(ovalIn: morphedFrame).cgPath
morphAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
circleLayer.add(morphAnimation, forKey: nil)
maskLayer.add(morphAnimation, forKey: nil)
}