iOS 实现闪电动画效果

看到手机中天气闪电效果挺炫酷的,就想试着实现其效果,费了一番功夫,实现了大致的效果,还有许多地方需要改进.

使用到的有UIBezierPath,CAShapeLayer,CABasicAnimation,CAAnimationGroup等.

实现的大致思路,就是需要绘制出闪电的路径,包括主干路径和分支路径,最后添加动画效果.

要想绘制路径就需要知道路径的点,在网上搜索到一个方法可以得到闪电的路径的点.如下:

/**

*  设置闪电的主干的点

*/

- (void)setupLightPointArrWithStartPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint displace:(CGFloat)displace

{

CGFloat midX = startPoint.x;

CGFloat midY = startPoint.y;

[pointArr removeAllObjects];

[pointArr addObject:NSStringFromCGPoint(startPoint)];

while (midY < endPoint.y)

{

if (startPoint.x <  kScreenWidth/2 )

{

midX += (arc4random()%3 - 0.5)*displace;

midY += (arc4random()%5 - 0.5)*displace;

}else

{

midX -= (arc4random()%3 - 0.5)*displace;

midY += (arc4random()%5 - 0.5)*displace;

}

[pointArr addObject:NSStringFromCGPoint(CGPointMake(midX, midY))];

}

}


其中闪电分支的获取点也是如此.

注意:其中分支的起点是主干上的点.当然也可以不是.

需要的点都已经获取到了,就需要绘制了.

/**

*  设置闪电的路径

*/

- (void)setupLightningPath

{

UIBezierPath *path = [UIBezierPath bezierPath];

[bezierPathArr addObject:path];

CGPoint point ;

for (int i = 0; i < pointArr.count; i ++)

{

point = CGPointFromString(pointArr[i]);

if (i == 0)

{

//画线,设置起点

[path moveToPoint:point];

}else

{

//设置第二个条线的终点,会自动把上一个终点当做起点

[path addLineToPoint:point];

}

NSLog(@"-----point%@ ",NSStringFromCGPoint(point));

if ([branchLightningStartPointArr containsObject:NSStringFromCGPoint(point)])

{

NSMutableArray *branchPointArr = [self setupBranchLightningPathPointWithStartPoint:CGPointMake(point.x, point.y) endPoint:CGPointMake(point.x + 100, point.y + 100) displace:1];

UIBezierPath *branchPath = [UIBezierPath bezierPath];

CGPoint branchPoint;

for (int j = 0; j < branchPointArr.count; j ++)

{

branchPoint = CGPointFromString(branchPointArr[j]);

if (j == 0)

{

//画线,设置起点

[branchPath moveToPoint:branchPoint];

}else

{

//设置第二个条线的终点,会自动把上一个终点当做起点

[branchPath addLineToPoint:branchPoint];

}

}

[bezierPathArr addObject:branchPath];

}

}

}

闪电的路径绘制完成以后就需要实现其动画效果.

/**

*  设置闪电的动画效果

*/

- (void)setupLightningAnimation

{

CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];

pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];

pathAnimation.duration = 0.2;

pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];

pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];

pathAnimation.repeatCount = 1;

//透明度

CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];

opacityAnimation.fromValue = [NSNumber numberWithFloat:1.0];

opacityAnimation.toValue = [NSNumber numberWithFloat:0.0];

CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];

groupAnimation.duration = 1.0;

groupAnimation.animations = @[[self opacityForever_Animation:0.1], pathAnimation,opacityAnimation];

groupAnimation.autoreverses = YES;

groupAnimation.repeatCount = 1;

for (int i = 0; i < bezierPathArr.count; i ++)

{

UIBezierPath *path = bezierPathArr[i];

CAShapeLayer *pathLayer = [CAShapeLayer layer];

pathLayer.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));

pathLayer.path = path.CGPath;

pathLayer.strokeColor = [[UIColor whiteColor] CGColor];

pathLayer.fillColor = nil;

pathLayer.lineWidth = (i == 0?1.0f:0.5);

pathLayer.lineJoin = kCALineJoinMiter;

[self.layer addSublayer:pathLayer];

[pathLayer addAnimation:groupAnimation forKey:@"xxx"];

}

}

至此动画简单的闪电效果已经完成了.还有许多地方需要继续完善.

更新了demo效果如下:


iOS 实现闪电动画效果_第1张图片
图片发自App

上传到了Github:https://github.com/ITXIN/AnimationShow

你可能感兴趣的:(iOS 实现闪电动画效果)