Swift 简单动画

一: 效果

a: 图形做 bounds动画
b: 线条做跟随动画
c: 圆点逐渐呈现动画
d: 图标做轨迹动画

Animation.gif

二:代码

static let animationDucation: CFTimeInterval = 3

override func viewDidLoad() {
    super.viewDidLoad()
    
    
    // MARK: 矩形 动画部分
    let path = UIBezierPath()
    
    path.move(to: CGPoint(x: 20, y: 300))       // 起点
    
    path.addLine(to: CGPoint(x: 40, y: 100))
    path.addLine(to: CGPoint(x: 80, y: 200))
    path.addLine(to: CGPoint(x: 150, y: 60))
    path.addLine(to: CGPoint(x: 200, y: 100))
    
    path.addLine(to: CGPoint(x: 340, y: 300))   // 右终点
    path.addLine(to: CGPoint(x: 20, y: 300))   // 闭圈
    
    let contentLayer = CALayer()
    contentLayer.frame = self.view.frame
    
    // 1: 画一个自下而上的渐变图
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = CGRect(x: 0, y: 0, width: 0, height: 300)
    gradientLayer.startPoint = CGPoint(x: 0, y: 1)
    gradientLayer.endPoint = CGPoint(x: 0, y: 0)
    gradientLayer.colors = [
        UIColor(red: 185 / 255.0, green: 185 / 255.0, blue: 200 / 255.0, alpha: 1).cgColor,
        UIColor(red: 240 / 255.0, green: 240 / 255.0, blue: 240 / 255.0, alpha: 1).cgColor]
    gradientLayer.locations = [0.01, 0.5]   // colors 元素的起点
    contentLayer.addSublayer(gradientLayer)
    
    // 2: 用贝塞尔构建的形状 贴住渐变图(图形以外不可见)
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = path.cgPath
    shapeLayer.fillColor = UIColor.green.cgColor
    contentLayer.mask = shapeLayer
    
    self.view.layer.addSublayer(contentLayer)
    
    // Animation
    let animation = CABasicAnimation(keyPath: "bounds")
    animation.duration = ProfileViewController.animationDucation
    // toValue width 是 frame width的 2 倍,不然动画不完全 不知道为什么
    animation.toValue = NSValue(cgRect: CGRect(x: 0, y: 0, width: 680, height: 300))
    animation.timingFunction = CAMediaTimingFunction(name: .linear)
    animation.fillMode = .forwards
    animation.autoreverses = false
    animation.isRemovedOnCompletion = false
    gradientLayer.add(animation, forKey: "bounds")
    
    
    // MARK: 滚动线条 部分
    let linePath = UIBezierPath()
    
    linePath.move(to: CGPoint(x: 20, y: 300))       // 起点
    linePath.addLine(to: CGPoint(x: 40, y: 100))
    
    linePath.addLine(to: CGPoint(x: 80, y: 200))
    linePath.addLine(to: CGPoint(x: 150, y: 60))
    linePath.addLine(to: CGPoint(x: 200, y: 100))
    linePath.addLine(to: CGPoint(x: 340, y: 300))   // 右终点
    
    let lineShapeLayer = CAShapeLayer()
    lineShapeLayer.path = linePath.cgPath
    lineShapeLayer.strokeColor = UIColor.red.cgColor
    lineShapeLayer.fillColor = nil
    lineShapeLayer.lineWidth = 1
    self.view.layer.addSublayer(lineShapeLayer)
    
    // Animation
    let lineAnimation = CABasicAnimation(keyPath: "strokeEnd")
    lineAnimation.duration = ProfileViewController.animationDucation
    lineAnimation.fromValue = 0
    lineAnimation.toValue = 1
    lineAnimation.timingFunction = CAMediaTimingFunction(name: .easeIn)
    lineAnimation.fillMode = .forwards
    lineAnimation.autoreverses = false
    lineAnimation.isRemovedOnCompletion = false
    lineShapeLayer.add(lineAnimation, forKey: "strokeEnd")
    
    // MARK: 小圆点部分
    
    let circlePath = UIBezierPath()
    circlePath.move(to: CGPoint(x: 40, y: 100))
    circlePath.addArc(withCenter: CGPoint(x: 40, y: 100), radius: 10, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
    
    circlePath.move(to: CGPoint(x: 80, y: 200))
    circlePath.addArc(withCenter: CGPoint(x: 80, y: 200), radius: 10, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
    
    circlePath.move(to: CGPoint(x: 150, y: 60))
    circlePath.addArc(withCenter: CGPoint(x: 150, y: 60), radius: 10, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
    
    circlePath.move(to: CGPoint(x: 200, y: 100))
    circlePath.addArc(withCenter: CGPoint(x: 200, y: 100), radius: 10, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
    
    let circleShapeLayer = CAShapeLayer()
    circleShapeLayer.path = circlePath.cgPath
    circleShapeLayer.fillColor = UIColor(red: 185 / 255.0, green: 185 / 255.0, blue: 200 / 255.0, alpha: 1).cgColor
    circleShapeLayer.lineWidth = 1
    self.view.layer.addSublayer(circleShapeLayer)
    
    // Animation
    let circleAnimation = CABasicAnimation(keyPath: "opacity")
    circleAnimation.duration = ProfileViewController.animationDucation
    circleAnimation.fromValue = 0.3
    circleAnimation.toValue = 1
    circleAnimation.timingFunction = CAMediaTimingFunction(name: .easeIn)
    circleAnimation.fillMode = .forwards
    circleAnimation.autoreverses = false
    circleAnimation.isRemovedOnCompletion = false
    circleShapeLayer.add(circleAnimation, forKey: "opacity")

   // MARK: 小图标部分
     let carLayer: CALayer = CALayer()
    carLayer.frame = CGRect(x: 0, y: 0, width: 36, height: 36)
    carLayer.contents = UIImage.init(named: "sharelogo")!.cgImage

    let carAnimation = CAKeyframeAnimation.init(keyPath: "position")
    carAnimation.path = linePath.cgPath
    carAnimation.timingFunction = CAMediaTimingFunction(name: .linear)
    carAnimation.duration = 6
    carAnimation.repeatCount = MAXFLOAT
    carAnimation.autoreverses = false
    carAnimation.calculationMode = .cubicPaced
    carAnimation.rotationMode = .rotateAuto
    self.view.layer.addSublayer(carLayer)
    carLayer.add(carAnimation, forKey: "carAnimation")

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351