zoukankan      html  css  js  c++  java
  • Swift

    Swift - EasingAnimation绘制圆环动画

    效果

    源码

    https://github.com/YouXianMing/Swift-Animations

    //
    //  CircleView.swift
    //  Swift-Animations
    //
    //  Created by YouXianMing on 16/8/16.
    //  Copyright © 2016年 YouXianMing. All rights reserved.
    //
    
    import UIKit
    
    // MARK: Public class : CircleView
    
    class CircleView: UIView {
        
        // MARK: Convenience init.
        
        convenience init(frame: CGRect, lineWidth : CGFloat, lineColor : UIColor, clockWise : Bool, startDegree : CGFloat) {
            
            self.init(frame : frame)
            self.lineWidth   = lineWidth
            self.lineColor   = lineColor
            self.clockWise   = clockWise
            self.startDegree = startDegree
            self.makeEffective()
        }
        
        // MARK: Properties.
        
        /// Line width, default is 1.0.
        var lineWidth    : CGFloat {
            
            get { if pLineWidth <= 0 { return 1} else {return pLineWidth}}
            set(newVal) { pLineWidth = newVal}
        }
        
        /// Line color, default is black color.
        var lineColor    : UIColor {
        
            get { if pLineColor == nil { return UIColor.blackColor()} else {return pLineColor}}
            set(newVal) { pLineColor = newVal}
        }
        
        /// Clock wise or not, default is true.
        var clockWise    : Bool    = true
        
        /// Start degrees (0° ~ 360°), default is 0.
        var startDegree  : CGFloat = 0
        
        // MARK: Methods.
        
        /**
         Make the config effective, when you set all the properties, you must run this method to make the config effective.
         */
        func makeEffective() {
            
            let size   = bounds.size
            let radius = size.width / 2.0 - lineWidth / 2.0
            
            var tmpStartAngle : CGFloat
            var tmpEndAngle   : CGFloat
            
            if clockWise == true {
                
                tmpStartAngle = -radianFromDegrees(180 - startDegree)
                tmpEndAngle   = radianFromDegrees(180 + startDegree)
                
            } else {
            
                tmpStartAngle = radianFromDegrees(180 - startDegree)
                tmpEndAngle   = -radianFromDegrees(180 + startDegree)
            }
            
            let circlePath           = UIBezierPath(arcCenter: CGPointMake(size.height / 2, size.width / 2),
                                                    radius: radius, startAngle: tmpStartAngle, endAngle: tmpEndAngle, clockwise: clockWise)
            pCircleLayer.path        = circlePath.CGPath
            pCircleLayer.fillColor   = UIColor.clearColor().CGColor
            pCircleLayer.strokeColor = lineColor.CGColor
            pCircleLayer.lineWidth   = lineWidth
            pCircleLayer.strokeEnd   = 0
        }
        
        /**
         Stroke start animation.
         
         - parameter value:          StrokeStart value, range is [0, 1].
         - parameter easingFunction: Easing function enum value.
         - parameter animated:       Animated or not.
         - parameter duration:       The animation's duration.
         */
        func strokeStart(value : Double, easingFunction : EasingFunction, animated : Bool, duration : NSTimeInterval) {
            
            var strokeStartValue = value
            
            if strokeStartValue <= 0 {
                
                strokeStartValue = 0
                
            } else if strokeStartValue >= 1 {
            
                strokeStartValue = 1
            }
            
            if animated == true {
                
                let easingValue          = EasingValue(withFunction: easingFunction, frameCount: Int(duration * 60.0))
                let keyAnimation         = CAKeyframeAnimation(keyPath: "strokeStart")
                keyAnimation.duration    = duration
                keyAnimation.values      = easingValue.frameValueWith(fromValue: Double(pCircleLayer.strokeStart), toValue: strokeStartValue)
                
                pCircleLayer.strokeStart = CGFloat(strokeStartValue)
                pCircleLayer.addAnimation(keyAnimation, forKey: nil)
                
            } else {
            
                CATransaction.setDisableActions(true)
                pCircleLayer.strokeStart = CGFloat(strokeStartValue)
                CATransaction.setDisableActions(false)
            }
        }
        
        /**
         Stroke end animation.
         
         - parameter value:          StrokeEnd value, range is [0, 1].
         - parameter easingFunction: Easing function enum value.
         - parameter animated:       Animated or not.
         - parameter duration:       The animation's duration.
         */
        func strokeEnd(value : Double, easingFunction : EasingFunction, animated : Bool, duration : NSTimeInterval) {
            
            var strokeStartValue = value
            
            if strokeStartValue <= 0 {
                
                strokeStartValue = 0
                
            } else if strokeStartValue >= 1 {
                
                strokeStartValue = 1
            }
            
            if animated == true {
                
                let easingValue        = EasingValue(withFunction: easingFunction, frameCount: Int(duration * 60.0))
                let keyAnimation       = CAKeyframeAnimation(keyPath: "strokeEnd")
                keyAnimation.duration  = duration
                keyAnimation.values    = easingValue.frameValueWith(fromValue: Double(pCircleLayer.strokeEnd), toValue: strokeStartValue)
                
                pCircleLayer.strokeEnd = CGFloat(strokeStartValue)
                pCircleLayer.addAnimation(keyAnimation, forKey: nil)
                
            } else {
                
                CATransaction.setDisableActions(true)
                pCircleLayer.strokeEnd = CGFloat(strokeStartValue)
                CATransaction.setDisableActions(false)
            }
        }
        
        // MARK: Private value & func & system method.
        
        override init(frame: CGRect) {
            
            super.init(frame: frame)
            pCircleLayer       = CAShapeLayer()
            pCircleLayer.frame = bounds
            layer.addSublayer(pCircleLayer)
        }
        
        required init?(coder aDecoder: NSCoder) {
            
            fatalError("init(coder:) has not been implemented")
        }
        
        private var pCircleLayer : CAShapeLayer!
        private var pLineWidth   : CGFloat! = 1
        private var pLineColor   : UIColor! = UIColor.blackColor()
        
        private func radianFromDegrees(degrees : CGFloat) -> CGFloat {
        
            return (CGFloat(M_PI) * degrees) / 180.0
        }
    }
  • 相关阅读:
    js 字符串转化成数字
    web项目中各种路径的获取
    个人作业——软件工程实践总结作业
    Beta 答辩总结
    Beta 冲刺 (7/7)
    Beta 冲刺 (6/7)
    Beta 冲刺 (5/7)
    Beta 冲刺 (4/7)
    Beta 冲刺 (3/7)
    软件产品案例分析(团队)
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/5778079.html
Copyright © 2011-2022 走看看