iOS 實(shí)現(xiàn)閃電動畫效果

看到手機(jī)中天氣閃電效果挺炫酷的,就想試著實(shí)現(xiàn)其效果,費(fèi)了一番功夫,實(shí)現(xiàn)了大致的效果,還有許多地方需要改進(jìn).

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

實(shí)現(xiàn)的大致思路,就是需要繪制出閃電的路徑,包括主干路徑和分支路徑,最后添加動畫效果.

要想繪制路徑就需要知道路徑的點(diǎn),在網(wǎng)上搜索到一個方法可以得到閃電的路徑的點(diǎn).如下:

/**

* ?設(shè)置閃電的主干的點(diǎn)

*/

- (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))];

}

}


其中閃電分支的獲取點(diǎn)也是如此.

注意:其中分支的起點(diǎn)是主干上的點(diǎn).當(dāng)然也可以不是.

需要的點(diǎn)都已經(jīng)獲取到了,就需要繪制了.

/**

* ?設(shè)置閃電的路徑

*/

- (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)

{

//畫線,設(shè)置起點(diǎn)

[path moveToPoint:point];

}else

{

//設(shè)置第二個條線的終點(diǎn),會自動把上一個終點(diǎn)當(dāng)做起點(diǎn)

[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)

{

//畫線,設(shè)置起點(diǎn)

[branchPath moveToPoint:branchPoint];

}else

{

//設(shè)置第二個條線的終點(diǎn),會自動把上一個終點(diǎn)當(dāng)做起點(diǎn)

[branchPath addLineToPoint:branchPoint];

}

}

[bezierPathArr addObject:branchPath];

}

}

}

閃電的路徑繪制完成以后就需要實(shí)現(xiàn)其動畫效果.

/**

* ?設(shè)置閃電的動畫效果

*/

- (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"];

}

}

至此動畫簡單的閃電效果已經(jīng)完成了.還有許多地方需要繼續(xù)完善.

更新了demo效果如下:


圖片發(fā)自簡書App

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容