动画绘制水波纹

动画绘制水波纹_ico

使用drawRect:方式绘制的动画效果,右图为占用了多少CPU.

动画绘制水波纹_重要_02动画绘制水波纹_iOS_03

虽然画起来挺好看的,但占用的内存真心吃不消,原因其实很简单哦,drawRect:方法只调用CPU进行图形绘制,所以非常非常的消耗CPU性能,把它集成到应用程序中,我觉得是不靠谱的呢.



//
// WaterView.h
// Cell
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface WaterView : UIView

@end



//
// WaterView.m
// Cell
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "WaterView.h"

@interface WaterView ()

{
UIColor *_currentWaterColor;
float _currentLinePointY;

float a;
float b;

BOOL flag;
}

@end

@implementation WaterView

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self setBackgroundColor:[UIColor clearColor]];

a = 1.5;
b = 0;
flag = NO;

_currentWaterColor = [UIColor colorWithRed:86/255.0f
green:202/255.0f
blue:139/255.0f
alpha:1];

_currentLinePointY = 250;

[NSTimer scheduledTimerWithTimeInterval:0.02
target:self
selector:@selector(linkRun)
userInfo:nil
repeats:YES];
}
return self;
}

- (void)linkRun
{
if (flag) {
a += 0.01;
}else{
a -= 0.01;
}

if (a<=1) {
flag = YES;
}

if (a>=1.5) {
flag = NO;
}

b+=0.1;

[self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect
{
// 获取一个path
CGMutablePathRef path = CGPathCreateMutable();

{
// 移动到起始点
CGPathMoveToPoint(path, nil, 0, 100);

// 绘制水平方向上所有的点
float y = _currentLinePointY;
CGPathMoveToPoint(path, NULL, 0, y);
for(float x = 0; x <= 320; x++)
{
y= a * sin(x/180.f * M_PI + 4*b / M_PI) * 5 + _currentLinePointY;
CGPathAddLineToPoint(path, nil, x, y);
}

// 移动到屏幕底部
CGPathAddLineToPoint(path, nil, 320, rect.size.height);
CGPathAddLineToPoint(path, nil, 0, rect.size.height);

// 闭合曲线
CGPathAddLineToPoint(path, nil, 0, _currentLinePointY);
}

// 获取绘制句柄
CGContextRef context = UIGraphicsGetCurrentContext();

// 设置线宽为1
CGContextSetLineWidth(context, 1);

// 设置颜色为红色
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);

// context接受path
CGContextAddPath(context, path);

// context填充path
CGContextFillPath(context);

// 描绘path
CGContextDrawPath(context, kCGPathStroke);

// 释放path
CGPathRelease(path);
}

@end


以下效果:

动画绘制水波纹_重要_04动画绘制水波纹_重要_05

效率相差十万八千里呢,这是因为CoreAnimation使用GPU渲染,所以不仅流畅,还消耗CPU,如果配置的路径多一些,动画效果将会非常流畅的.



//
// RootViewController.m
// Cell
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "YXGCD.h"

@interface RootViewController ()

@property (nonatomic, strong) GCDTimer *timer;

@end

@implementation RootViewController

- (void)viewDidLoad
{
[super viewDidLoad];

self.view.backgroundColor = [UIColor blackColor];

// shapeLayer
CAShapeLayer *circleLayer = [CAShapeLayer layer];
circleLayer.frame = (CGRect){CGPointMake(0, 0), CGSizeMake(200, 200)};
circleLayer.position = self.view.center;
circleLayer.path = [self path1].CGPath;
circleLayer.fillColor = [UIColor redColor].CGColor;
circleLayer.strokeColor = [UIColor redColor].CGColor;
circleLayer.lineWidth = 2.f;
[self.view.layer addSublayer:circleLayer];

// 定时器
_timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
[_timer event:^{
static int i = 0;
if (i++ % 2 == 0)
{
CABasicAnimation *circleAnim = [CABasicAnimation animationWithKeyPath:@"path"];
circleAnim.removedOnCompletion = NO;
circleAnim.duration = 1;
circleAnim.fromValue = (__bridge id)(circleLayer.path);
circleAnim.toValue = (__bridge id)[self path2].CGPath;
circleLayer.path = [self path2].CGPath;
[circleLayer addAnimation:circleAnim forKey:@"animateCirclePath"];
}
else
{
CABasicAnimation *circleAnim = [CABasicAnimation animationWithKeyPath:@"path"];
circleAnim.removedOnCompletion = NO;
circleAnim.duration = 1;
circleAnim.fromValue = (__bridge id)(circleLayer.path);
circleAnim.toValue = (__bridge id)[self path1].CGPath;
circleLayer.path = [self path1].CGPath;
[circleLayer addAnimation:circleAnim forKey:@"animateCirclePath"];
}
} timeInterval:NSEC_PER_SEC];
[_timer start];

}

- (UIBezierPath *)path1
{
//// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(0.5, 38.5)];
[bezierPath addCurveToPoint: CGPointMake(124.5, 38.5) controlPoint1: CGPointMake(0.5, 38.5) controlPoint2: CGPointMake(74.82, 114.88)];
[bezierPath addCurveToPoint: CGPointMake(240.5, 38.5) controlPoint1: CGPointMake(174.18, -37.88) controlPoint2: CGPointMake(240.5, 38.5)];
[bezierPath addLineToPoint: CGPointMake(240.5, 120.5)];
[bezierPath addLineToPoint: CGPointMake(0.5, 120.5)];
[bezierPath addLineToPoint: CGPointMake(0.5, 38.5)];
[bezierPath closePath];

return bezierPath;
}

- (UIBezierPath *)path2
{
//// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(0.5, 38.5)];
[bezierPath addCurveToPoint: CGPointMake(124.5, 38.5) controlPoint1: CGPointMake(0.5, 38.5) controlPoint2: CGPointMake(64.14, -22.65)];
[bezierPath addCurveToPoint: CGPointMake(240.5, 38.5) controlPoint1: CGPointMake(184.86, 99.65) controlPoint2: CGPointMake(240.5, 38.5)];
[bezierPath addLineToPoint: CGPointMake(240.5, 120.5)];
[bezierPath addLineToPoint: CGPointMake(0.5, 120.5)];
[bezierPath addLineToPoint: CGPointMake(0.5, 38.5)];
[bezierPath closePath];

return bezierPath;
}

@end


不过,使用path路径动画绘制波形图需要考验你的空间感觉了.

动画绘制水波纹_ico_06