UIImage镂空动画

2017-06-05  本文已影响0人  那女孩偷我心

效果如下


shot.gif

实现步骤:
1.首先用UIBezierPath创建一个镂空圆,然后添加镂空圆到UIImageView上。
2.创建镂空圆放大动画。
创建UIImageView的拓展类,在其中创建一个属性用于存储之后要用到的CAShapeLayer对象

 fileprivate(set)  var maskLayer:CAShapeLayer? {
        get{
        return objc_getAssociatedObject(self, &key) as? CAShapeLayer
        }
        set(newValue){
        objc_setAssociatedObject(self, &key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

创建方法,用于外部调用添加动画

    public func addCircleOddAnim(){
        self.clipsToBounds = true
        self.addMaskView()//添加遮罩
        self.addamin()//添加动画
    }

addMaskView方法用于添加遮罩层,初始全灰色半透明。

private func addMaskView(){
        //UIImageView中心点
        let centerX = self.bounds.size.width/2
        let centerY = self.bounds.size.height/2
        //圆的半径
        let r = sqrt((centerX)*(centerY)+(centerY)*(centerY))
       //在图片中心创建一个宽高为0的圆
        let innerRect :CGRect = CGRect(x: centerX, y:centerY, width: 0, height: 0)
       //外层圆,整个圆比UIImageView大一圈,可见下图
        let outerRect :CGRect = CGRect(x: centerX-r, y: centerY-r, width: 2*r, height: 2*r)
        if self.maskLayer == nil {
        self.maskLayer = CAShapeLayer()
        }
        let innerPath = UIBezierPath(ovalIn: innerRect)
        let outerPath = UIBezierPath(ovalIn: outerRect)
        //两条path合并到一起
        outerPath.append(innerPath)
        outerPath.usesEvenOddFillRule = true
        self.maskLayer!.path=outerPath.cgPath
       //填充规则为补集方式
        self.maskLayer!.fillRule = kCAFillRuleEvenOdd
        self.maskLayer!.fillColor = UIColor(colorLiteralRed: 0.2, green: 0.2, blue: 0.2, alpha: 0.7).cgColor
        self.layer.addSublayer(self.maskLayer!)
    }
yuandian.png
private func addamin(){
        //创建动画对象
        let circleScaleAnim:CABasicAnimation = CABasicAnimation(keyPath: "path")
        //起始点shapeLayer的已经创建好的path、即是图片全灰遮罩
        let fromBezier = UIBezierPath(cgPath: self.maskLayer!.path!)
        circleScaleAnim.fromValue=fromBezier.cgPath
        //UIImageView中心点
        let centerX = self.bounds.size.width/2
        let centerY = self.bounds.size.height/2
        //圆的半径
        let r = sqrt((centerX)*(centerY)+(centerY)*(centerY))
        //外层圆
        let maskPath:UIBezierPath = UIBezierPath(ovalIn: CGRect(x: centerX-r, y: centerY-r, width: 2*r, height: 2*r))
        //内层圆与外层圆交汇
        let innerPath:UIBezierPath = UIBezierPath(ovalIn: CGRect(x: centerX-r, y: centerY-r, width: 2*r, height: 2*r))
        //取内层圆和外层圆的补集(根本不存在,两个圆交汇在一起)
        maskPath.usesEvenOddFillRule = true
        maskPath.append(innerPath)
        circleScaleAnim.toValue = maskPath.cgPath
        circleScaleAnim.duration = 1
        //动画执行后保持动画执行后的效果
        circleScaleAnim.fillMode = kCAFillModeForwards
        circleScaleAnim.isRemovedOnCompletion = false
        self.maskLayer!.add(circleScaleAnim, forKey: "path")  
    }

到这里简单的镂空圆动画就完成了

上一篇下一篇

猜你喜欢

热点阅读