CoreAnimation研究(2)
demo git地址
在第一篇提到了CoreAnimation水很深,之所以着么说,是因为它除了普通的动画效果外,还有很多很高级的玩法。
CAShapeLayer
如果你厌倦了动画只是简单的对uiview的各种属性操作,想自己画点图形怎么办?CAShapeLayer是一个不错的选择!一言不合上代码:
//画圆
let bPath = UIBezierPath(arcCenter: CGPoint(x: 100, y: 100), radius: 60, startAngle: 0, endAngle: CGFloat(M_PI*2), clockwise: true);
let sLayer = CAShapeLayer();
sLayer.path = bPath.cgPath;
sLayer.fillColor = UIColor.clear.cgColor;
sLayer.strokeColor = UIColor.green.cgColor;
view.layer.addSublayer(sLayer);
//如果想要一个实心圆,只要把fillColor改成想要的颜色即可
既然是动画,肯定不可能满足于画一个静态的图像,怎么让画的图形动起来呢?下面的代码会画出一条向两头延伸的曲线:
//先画一条曲线
let sP = CGPoint(x: 0, y: 0);
let eP = CGPoint(x: 200, y: 200);
//两个控制点
let cPA = CGPoint(x: 150, y: 100);
let cPB = CGPoint(x: 50, y: 200);
let sLayer = CAShapeLayer();
let bPath = UIBezierPath();
bPath.move(to: sP);
bPath.addCurve(to: eP, controlPoint1: cPA, controlPoint2: cPB);
// bPath.addQuadCurve(to: eP, controlPoint: cPA);
sLayer.path = bPath.cgPath;
sLayer.fillColor = UIColor.clear.cgColor;
sLayer.strokeColor = UIColor.green.cgColor;
view.layer.addSublayer(sLayer);
//向上延伸的动画
let animationS = CABasicAnimation(keyPath: "strokeStart");
animationS.fromValue = 0.5;
animationS.toValue = 0;
animationS.duration = 2;
//向下延伸的动画
let animationE = CABasicAnimation(keyPath: "strokeEnd");
animationE.fromValue = 0.5;
animationE.toValue = 1;
animationE.duration = 2;
sLayer.add(animationS, forKey: nil);
sLayer.add(animationE, forKey: nil);
弹簧动画:CASpringAnimation
过去弹簧动画,都是靠keyFrame动画来模拟的,iOS9后引入了CASpringAnimation,实现起来简单很多
参数介绍:
- mass:质量,质量越大,弹性越大,需要的动画时间越长,默认是1 必须大于0。
- stiffness:刚度系数,刚度系数越大,产生形变的力就越大,运动越快,必须大于0 ,默认是100。
- damping:阻尼系数,阻止弹簧伸缩的系数。阻尼系数越大,停止越快。时间越短。 默认是10 必须大于或者等于0。
- initialVelocity:初始速度,正负代表方向,数值代表大小, 默认是0。
- settlingDuration:计算从开始到结束的动画的时间,根据当前的参数估算时间,只读的,不能赋值。
animation.duration
= animation.settlingDuration;
let sAnimation = CASpringAnimation();
sAnimation.keyPath = "bounds";
sAnimation.toValue = NSValue(cgRect: CGRect(x: 0, y: 0, width: Int(rV.frame.width*1.5), height: Int(rV.frame.height*1.5)));
sAnimation.mass = 2;//质量
sAnimation.stiffness = 100;//刚度
sAnimation.damping = 3;//阻尼
sAnimation.initialVelocity = 50;//初始速度
sAnimation.duration = sAnimation.settlingDuration;
rV.layer.add(sAnimation, forKey: nil);
粒子系统:CAEmitterLayer
CoreAnimation最神奇的地方,就是粒子系统了。用CAEmitterLayer可以做出很多炫酷的效果。
CAEmitterLayer
参数介绍:
- emitterPosition:发射位置
- emitterSize:发射源的大小
- emitterMode:发射模式
- kCAEmitterLayerPoints
- kCAEmitterLayerOutline
- kCAEmitterLayerSurface
- kCAEmitterLayerVolume
- emitterShape:发射源的形状:
- kCAEmitterLayerPoint
- kCAEmitterLayerLine
- kCAEmitterLayerRectangle
- kCAEmitterLayerCuboid
- kCAEmitterLayerCircle
- kCAEmitterLayerSphere
- renderMode:渲染模式:
- kCAEmitterLayerUnordered
- kCAEmitterLayerOldestFirst
- kCAEmitterLayerOldestLast
- kCAEmitterLayerBackToFront
- kCAEmitterLayerAdditive
- birthRate:粒子产生系数,默认1.0
- emitterCells: 装着CAEmitterCell对象的数组,被用于把粒子投放到layer上
- emitterDepth:决定粒子形状的深度联系:emitter shape
- emitterZposition:发射源的z坐标位置
- lifetime:粒子生命周期
- preservesDepth:不是多很清楚(粒子是平展在层上)
- scale:粒子的缩放比例:
- seed:用于初始化随机数产生的种子
- spin:自旋转速度
- velocity:粒子速度
CAEmitterCell
CAEmitterCell类代从从CAEmitterLayer射出的粒子;emitter cell定义了粒子发射的方向。
参数介绍:
- alphaRange: 一个粒子的颜色alpha能改变的范围
- alphaSpeed:粒子透明度在生命周期内的改变速度
- birthrate:粒子参数的速度乘数因子;每秒发射的粒子数量
- blueRange:一个粒子的颜色blue 能改变的范围
- blueSpeed: 粒子blue在生命周期内的改变速度
- color:粒子的颜色
- contents:是个CGImageRef的对象,既粒子要展现的图片
- contentsRect:应该画在contents里的子rectangle
- emissionLatitude:发射的z轴方向的角度
- emissionLongitude:x-y平面的发射方向
- emissionRange;周围发射角度
- emitterCells:粒子发射的粒子
- enabled:粒子是否被渲染
- greenrange: 一个粒子的颜色green 能改变的范围
- greenSpeed: 粒子green在生命周期内的改变速度
- lifetime:生命周期
- lifetimeRange:生命周期范围 lifetime= lifetime(+/-) lifetimeRange
- magnificationFilter:不是很清楚好像增加自己的大小
- minificatonFilter:减小自己的大小
- minificationFilterBias:减小大小的因子
- name:粒子的名字
- redRange:一个粒子的颜色red 能改变的范围
- redSpeed; 粒子red在生命周期内的改变速度
- scale:缩放比例
- scaleRange:缩放比例范围
- scaleSpeed:缩放比例速度
- spin:子旋转角度
- spinrange:子旋转角度范围
- style:不是很清楚:
- velocity:速度
- velocityRange:速度范围
- xAcceleration:粒子x方向的加速度分量
- yAcceleration:粒子y方向的加速度分量
- zAcceleration:粒子z方向的加速度分量
下面贴一个示例,模拟一个下雪的效果:
let emitter = CAEmitterLayer();
view.layer.addSublayer(emitter);
emitter.emitterShape = kCAEmitterLayerRectangle;
let rect = CGRect(x: 0.0, y: 0.0, width: view.bounds.width, height: 50.0)
emitter.emitterPosition = CGPoint(x:rect.width/2, y:rect.height/2);
emitter.emitterSize = rect.size;
let emitterCell = CAEmitterCell()
emitterCell.contents = UIImage(named: "snow")?.cgImage;
emitterCell.birthRate = 120 //每秒产生120个粒子
emitterCell.lifetime = 3 //存活1秒
emitterCell.lifetimeRange = 3.0
emitter.emitterCells = [emitterCell] //这里可以设置多种粒子 我们以一种为粒子
emitterCell.yAcceleration = 70.0 //给Y方向一个加速度
emitterCell.xAcceleration = 20.0 //x方向一个加速度
emitterCell.velocity = 20.0 //初始速度
emitterCell.emissionLongitude = CGFloat(-M_PI) //向左
emitterCell.velocityRange = 200.0 //随机速度 -200+20 --- 200+20
emitterCell.emissionRange = CGFloat(M_PI_2) //随机方向 -pi/2 --- pi/2
//emitterCell.color = UIColor(red: 0.9, green: 1.0, blue: 1.0,
// alpha: 1.0).CGColor //指定颜色
emitterCell.redRange = 0.3
emitterCell.greenRange = 0.3
emitterCell.blueRange = 0.3 //三个随机颜色
emitterCell.scale = 0.8
emitterCell.scaleRange = 0.8 //0 - 1.6
emitterCell.scaleSpeed = -0.15 //逐渐变小
emitterCell.alphaRange = 0.75 //随机透明度
emitterCell.alphaSpeed = -0.15 //逐渐消失
self.view.layer.addSublayer(emitter);