首页 > 代码库 > 动画绘制水波纹

动画绘制水波纹

动画绘制水波纹

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

虽然画起来挺好看的,但占用的内存真心吃不消,原因其实很简单哦,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

以下效果:

效率相差十万八千里呢,这是因为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路径动画绘制波形图需要考验你的空间感觉了.