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")

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。