美文网首页
如何在 Mac 上实现环形 loading 动画

如何在 Mac 上实现环形 loading 动画

作者: _我和你一样 | 来源:发表于2019-07-06 18:21 被阅读0次

    如何在 Mac 上实现环形 loading 动画

    网上也有很多 loading 动画,但每个公司的需求可能不同,网上找了很多可以在 Mac 上用的,要不和需求融入不方便吗,要么就是有很多多余的功能。

    我们的需求不展示进度,展示的是几种状态,状态不同,执行的动画也不同。

    我们状态共 4 种:

    • 连接中 connecting :圆弧,顺时针旋转

    • 连接完成 connected:在连接基础上,把圆弧动画为整圆

    • 断开连接中 disconnecting:圆弧,逆时针旋转

    • 断开完成 disconected:在上一个动画基础上,把圆弧动画为 0

    本想传个 gif 图的,没工具,下了个录不出效果。。。录了个视频,简书md 不支持。。。

    下面说下实现思路:

    通过自定义 NSView 来实现。主要用到绘图相关的知识。

    各个状态的动画分别实现,代码不多,注释很详细,不啰嗦了。

    import Cocoa
    
    class LoadingView: NSView {
        
        private var animationLayer:CAShapeLayer!
        
        override init(frame frameRect: NSRect) {
            super.init(frame: frameRect)
            basicInit()
        }
        
        required init?(coder decoder: NSCoder) {
            super.init(coder: decoder)
            basicInit()
        }
        
        private func basicInit() {
            wantsLayer = true
            animationLayer = CAShapeLayer()
            layer?.addSublayer(animationLayer)
            animationLayer.frame = bounds
            // 画圆
            let path = CGMutablePath()
            let center = CGPoint(x: bounds.width/2, y: bounds.height/2)
            path.addArc(center: center, radius: 0.9 * bounds.width/2, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
            animationLayer.path = path
            // 画边框(r:0.20 g:0.85 b:0.99 a:1.00)
            animationLayer.strokeColor = CGColor(red: 0.20, green: 0.85, blue: 0.99, alpha: 1.00)
            animationLayer.lineWidth = 5
            animationLayer.fillColor = NSColor.clear.cgColor// 清空填充颜色
            
            // 画部分圆环
            animationLayer.strokeEnd = 0.2
            animationLayer.isHidden = true
            // 动画在需要时进行调用
        }
        
        
        
        // 连接动画
        func connectingAnimation() {
            animationLayer.isHidden = false
            animationLayer.removeAllAnimations()
            let rotateAnimtion = CABasicAnimation(keyPath: "transform.rotation.z")
            let startValue = NSNumber(value: Float(2.0*CGFloat.pi))
            let endValue = NSNumber(value: 0)
            rotateAnimtion.fromValue = startValue
            rotateAnimtion.toValue = endValue
            rotateAnimtion.duration = 1
            rotateAnimtion.repeatCount = Float(CGFloat.greatestFiniteMagnitude)
            animationLayer.add(rotateAnimtion, forKey: "connecting")
        }
        
        // 连接成功动画
         func concectedAnimation() {
            animationLayer.isHidden = false
            let connectedAnimation = CABasicAnimation(keyPath: "strokeEnd")
            connectedAnimation.fromValue = NSNumber(value: 0.2)
            connectedAnimation.toValue = NSNumber(value: 1)
            connectedAnimation.duration = 1
            connectedAnimation.delegate = self
            animationLayer.add(connectedAnimation, forKey: "connected")
        }
        
        // 断开动画
        func disconcectAnimation() {
            animationLayer.isHidden = false
            let connectedAnimation = CABasicAnimation(keyPath: "strokeEnd")
            connectedAnimation.toValue = NSNumber(value: 0)
            connectedAnimation.duration = 0.5
            connectedAnimation.delegate = self
            connectedAnimation.fillMode = .forwards
            connectedAnimation.isRemovedOnCompletion = false
            animationLayer.add(connectedAnimation, forKey: "disconcect")
        }
        
        
        // 断开中动画
         func disconnectingAnimation() {
            animationLayer.isHidden = false
            animationLayer.removeAllAnimations()
            let rotateAnimtion = CABasicAnimation(keyPath: "transform.rotation.z")
            let startValue = NSNumber(value: Float(2.0*CGFloat.pi))
            let endValue = NSNumber(value: 0)
            rotateAnimtion.fromValue = endValue
            rotateAnimtion.toValue = startValue
            rotateAnimtion.duration = 1
            rotateAnimtion.repeatCount = Float(CGFloat.greatestFiniteMagnitude)
            animationLayer.add(rotateAnimtion, forKey: "disconnecting")
        }
    }
    
    extension LoadingView:CAAnimationDelegate {
        func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
            animationLayer.isHidden = true
            animationLayer.removeAllAnimations()
        }
    }
    
    

    相关文章

      网友评论

          本文标题:如何在 Mac 上实现环形 loading 动画

          本文链接:https://www.haomeiwen.com/subject/ezlmhctx.html