UIImage镂空动画

效果如下


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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 目录: 主要绘图框架介绍 CALayer 绘图 贝塞尔曲线-UIBezierPath CALayer子类 补充:i...
    Ryan___阅读 1,786评论 1 9
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 15,540评论 4 61
  • 显式动画 显式动画,它能够对一些属性做指定的自定义动画,或者创建非线性动画,比如沿着任意一条曲线移动。 属性动画 ...
    清风沐沐阅读 2,101评论 1 5
  • 目录 ** UIView 动画 ** ** Core Animation ** ** FaceBook POP动画...
    方向_4d0d阅读 1,819评论 0 3
  • 感赏老公给晶儿做早点,虽然不太好吃,但晶儿有心里准备,晶儿调侃说吃不死就行,感赏老公上班之前帮我给儿子洗澡洗衣服,...
    水墁金田阅读 274评论 0 0

友情链接更多精彩内容