一个小小的动画,太阳公公上山又下山。先上效果图。
用 lipecap 录的gif效果有点卡顿。好吧,说下如何实现的。
首先在一个大圆内先计算出内切九边形各个顶点的位置,接着连接相应的顶点变成一个九角星太阳的九条光芒,然后在九角星的中心画一个圈形的Layer,这样就大致画好了大阳的形状。
新建一个叫SunView的文件继承自UIView,然后在init方法内添加一个addSunLayer()的方法。并在里面添加以下方内容
class SunView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
addSunLayer()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
在addSunLayer()方法内添加绘制九角星的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | let ninePolyganPath:UIBezierPath = UIBezierPath() //大圆的半径 let radius:CGFloat = self .frame.size.width / 2 //九角星各个顶点的位置 var anglePoints:Dictionary<String,CGPoint> = Dictionary<String,CGPoint>() //第一个顶点的位置,最右边中间那个点 let firstPoint:CGPoint = CGPoint(x: bounds.width, y: bounds.width / 2) anglePoints[ "0" ] = firstPoint ninePolyganPath.moveToPoint(firstPoint) for i in 1..<9 { //将圆分成9份,每一份的大小为40度 let angle = Double(i) * 40.0 //算出相应角度的三角函数值 let rateSin:CGFloat = sin(CGFloat(angle / 180 * M_PI)) let rateCos:CGFloat = cos(CGFloat(angle / 180 * M_PI)) let x:CGFloat = radius * rateCos + radius let y:CGFloat = radius * rateSin + radius anglePoints[String(i)] = CGPoint(x: x, y: y) } //连接相应的九个点,使之成为九角星 ninePolyganPath.addLineToPoint(anglePoints[ "4" ]!) ninePolyganPath.addLineToPoint(anglePoints[ "8" ]!) ninePolyganPath.addLineToPoint(anglePoints[ "3" ]!) ninePolyganPath.addLineToPoint(anglePoints[ "7" ]!) ninePolyganPath.addLineToPoint(anglePoints[ "2" ]!) ninePolyganPath.addLineToPoint(anglePoints[ "6" ]!) ninePolyganPath.addLineToPoint(anglePoints[ "1" ]!) ninePolyganPath.addLineToPoint(anglePoints[ "5" ]!) ninePolyganPath.closePath() let ninePolyganLayer:CAShapeLayer = CAShapeLayer() ninePolyganLayer.fillColor = UIColor.yellowColor().CGColor ninePolyganLayer.strokeColor = UIColor.yellowColor().CGColor ninePolyganLayer.lineWidth = 5 ninePolyganLayer.path = ninePolyganPath.CGPath |
self.layer.addSublayer(ninePolyganLayer)
在ViewContoller文件内添加以下代码:
let sunView = SunView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
self.view.addSubview(sunView)
此时九角星就做好了,运行的效果如下:
接着要在九角星的中星心位置添加一个圆,做为太阳中心。添加一个计算属性,一个钜形的内切圆路径。
1 2 3 | var sunCirclePath:UIBezierPath { return UIBezierPath(ovalInRect: CGRect(x: self .frame.size.width * 0.3 / 2, y: self .frame.size.height * 0.3 / 2, width: self .frame.size.width - self .frame.size.width * 0.3, height: self .frame.size.height - self .frame.size.height * 0.3)) } |
接着在addSunLayer方法内添加以下内容:
1 2 3 4 5 6 | let sunLayer:CAShapeLayer = CAShapeLayer() sunLayer.path = sunCirclePath.CGPath sunLayer.lineWidth = 5 sunLayer.fillColor = UIColor.yellowColor().CGColor sunLayer.strokeColor = UIColor.colorWithHexString( "#eecc00" ).CGColor self .layer.addSublayer(sunLayer)<br><br> //让太阳转动起来 |
let animation:CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation")
animation.fromValue = 0.0
animation.toValue = 2 * M_PI
animation.duration = 5
animation.repeatCount = HUGE
layer.addAnimation(animation, forKey: nil)
并将上面ninePolyganLayer添加到图层的代码做如下修改。
self.layer.insertSublayer(ninePolyganLayer, below: sunLayer)
//self.layer.addSublayer(ninePolyganLayer)
此时运行效果如下:
最后就是让sunView按着指定的路径运行就可以了。回到ViewController文件内,添加以下计算路径属性,画出一条弧形路径,然后让太阳按着这个路径移动。
1 2 3 4 5 6 7 | var sunrisePath:UIBezierPath { let path:UIBezierPath = UIBezierPath() path.moveToPoint(CGPoint(x: 0, y: 160)) path.addQuadCurveToPoint(CGPoint(x: self .view.frame.size.width, y: 160), controlPoint: CGPoint(x: self .view.frame.size.width / 2, y: 60)) //path.closePath() //这个不能用, return path } |
添加以下动画代码
1 2 3 4 5 6 7 | let sunriseAnimation:CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position" ) sunriseAnimation.path = sunrisePath.CGPath sunriseAnimation.duration = 3<br>sunriseAnimation.calculationMode = kCAAnimationPaced sunriseAnimation.fillMode = kCAFillModeForwards sunriseAnimation.repeatCount = HUGE sunriseAnimation.removedOnCompletion = false sunView.layer.addAnimation(sunriseAnimation, forKey: nil ) |
这样就完成了。以上仅供参考,还请大家多提意见。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2012-07-12 SAP应用界面开发:5)Report List报表开发-实现Report的格式分页输出(6)
2012-07-12 SAP应用界面开发:5)Report List报表开发-输入列表颜色的设定(5)