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")
}
到这里简单的镂空圆动画就完成了