• 动画绘制水波纹


    动画绘制水波纹

    使用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路径动画绘制波形图需要考验你的空间感觉了.

  • 相关阅读:
    面试(转)
    Expression Blend实战开发技巧
    Twelve Principles of Agile Software
    Test Software Engineer
    Web开发工程师必读的15个设计博客
    麻省理工的C/C++的课程
    Orchard:处理1对多的关系
    DotNetNuke Switches to C# !!
    我的那个他
    2011 微软MVP全球大会
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3786168.html
Copyright © 2020-2023  润新知