写点什么

Swift 实现聚光灯动效

用户头像
关注
发布于: 25 分钟前
Swift 实现聚光灯动效

有时候 UI 上需要突出重点或者添加逐渐显示的效果,看起来就像聚光灯打在了图片上。



我们先来分析一下需要做哪些准备:


  1. 要想显示一个图像的部分内容,可以使用 CALayer 的 mask 属性设置遮罩,让 layer 显示 mask 遮住(非透明)的部分;

  2. 我们需要一个像聚光灯一样的遮罩,透明度从中间向外逐渐变高,即中间的透明度 alpha 为 1,四周的 0。

聚光灯遮罩

首先我们来看怎么绘制聚光灯效果的遮罩。模仿聚光灯的效果需要用到渐变。


渐变分为两种:


  1. 线性渐变:图形以直线的方式,朝着一个方向进行发散,发散后呈现矩形;

  2. 径向渐变:从指定的半径的大小开始,由往外或往内发散,发散后呈现出圆形。


在这里我们就是需要使用径向渐变


/// 聚光灯效果的遮罩class SpotlightFilterMaskLayer : CALayer {
/// 坡度的宽度 var gradientWidth: CGFloat = 40.0
/// 直径 var diameter: CGFloat = 0 { didSet { setNeedsDisplay() } } override func draw(in ctx: CGContext) { let origin: CGPoint = CGPoint(x: self.bounds.midX, y: self.bounds.midY) let clearRegionRadius: CGFloat = self.diameter * 0.5 let blurRegionRadius: CGFloat = clearRegionRadius + gradientWidth
// 创建颜色空间 let baseColorSpace = CGColorSpaceCreateDeviceRGB(); let colours : [CGFloat] = [0.0, 0.0, 0.0, 1, 0.0, 0.0, 0.0, 0.2] let colourLocations : [CGFloat] = [0, 1] // 创建渐变对象 // - colorSpace: 颜色空间 // - colorComponents: 颜色分量的强度值数组 // - locations: 渐变系数数组 // - count: 设置的渐变系数数组的元素个数 guard let gradient = CGGradient(colorSpace: baseColorSpace, colorComponents: colours, locations: colourLocations, count: 2) else { return }
// 绘制渐变 // - gradient: 渐变对象 // - startCenter: 起点 // - startRadius: 径向半径 // - endCenter: 终点 // - endRadius: 径向半径 // - options: 渐变模式 // - .drawsBeforeStartLocation 表示向里发散 // - .drawsAfterEndLocation 表示向外发散 ctx.drawRadialGradient(gradient, startCenter: origin, startRadius: clearRegionRadius, endCenter: origin, endRadius: blurRegionRadius, options: .drawsBeforeStartLocation);
ctx.drawPath(using: .fill) }}
复制代码

设置遮罩

直接通过 layer.mask 属性设置遮罩:


imageView.layer.mask = maskLayer
复制代码

添加动画

maskLayer 添加一个无限循环的 bounds 变化的动画。


func begin() {    let fromValue = imageView.bounds    let animation = CABasicAnimation(keyPath: "bounds")    animation.fromValue = fromValue    animation.toValue = CGRect(x: fromValue.origin.x - 100,                               y: fromValue.origin.y - 100,                               width: fromValue.size.width + 200,                               height: fromValue.size.height + 200)
animation.duration = 1 animation.autoreverses = true animation.repeatCount = MAXFLOAT animation.isRemovedOnCompletion = false maskLayer.add(animation, forKey: nil)}
复制代码

完整的代码

感兴趣可以查看完整的代码:SpotlightAnimation

用户头像

关注

还未添加个人签名 2017.10.17 加入

还未添加个人简介

评论

发布
暂无评论
Swift 实现聚光灯动效