你的位置:首页 > 操作系统

[操作系统]用drawRect以及CAReplicatorLayer绘制动态水波纹


用drawRect以及CAReplicatorLayer绘制动态水波纹

大大简化了写水波纹效果的难度,你可以根据示例自己组装水波纹效果,本设计是几个工具组合在一起完成的效果, DrawRectObject 以及 ReplicatorLineAnimationView 均可以独立完成更复杂的功能.

 

说明

1. 用sine计算正玄曲线

2. 用CAReplicatorLayer实现重复移动的效果

 

效果

 

源码

https://github.com/YouXianMing/UI-Component-Collection 中的 DrawRectObject

//// WaveView.h// DrawRectObject//// Created by YouXianMing on 16/8/1.// Copyright © 2016年 YouXianMing. All rights reserved.//#import "CustomDrawingView.h"typedef enum : NSUInteger {    kStrokeWave = 1 << 2,  kFillWave  = 1 << 3 ,  } EWaveViewType;@interface WaveView : CustomDrawingView/** * Wave type, default is kFillWave. */@property (nonatomic) EWaveViewType type;/** * Sine phase, default is 0. */@property (nonatomic) CGFloat phase;/** * Wave crest height, Default is 10. */@property (nonatomic) CGFloat waveCrest;/** * Full wave count, default is 1. */@property (nonatomic) NSInteger waveCount;/** * The fill style. */@property (nonatomic, strong) DrawingStyle *fillStyle;/** * The stroke style. */@property (nonatomic, strong) DrawingStyle *strokeStyle;@end

//// WaveView.m// DrawRectObject//// Created by YouXianMing on 16/8/1.// Copyright © 2016年 YouXianMing. All rights reserved.//#import "WaveView.h"@implementation WaveView- (instancetype)initWithFrame:(CGRect)frame {    if (self = [super initWithFrame:frame]) {      self.waveCrest = 10.f;    self.waveCount = 1;    self.phase   = 0.f;    self.type   = kFillWave;        DrawingStyle *fillStyle = [DrawingStyle new];    fillStyle.fillColor   = [DrawingColor colorWithUIColor:[[UIColor redColor] colorWithAlphaComponent:0.5f]];    self.fillStyle     = fillStyle;        DrawingStyle *strokeStyle = [DrawingStyle new];    strokeStyle.strokeColor  = [DrawingColor colorWithUIColor:[UIColor redColor]];    strokeStyle.lineWidth   = 0.5f;    self.strokeStyle     = strokeStyle;  }    return self;}- (void)drawRect:(CGRect)rect {    NSParameterAssert(self.fillStyle);  NSParameterAssert(self.strokeStyle);  [super drawRect:rect];    CGFloat width = self.frame.size.width;  CGFloat height = self.frame.size.height;  if (self.type & kFillWave) {        [self.drawRectObject useDrawingStyle:_fillStyle drawFillBlock:^(DrawRectObject *drawRectObject) {            for (CGFloat x = 0; x <= width; x++) {                if (x == 0) {                    [drawRectObject moveToStartPoint:CGPointMake(x, _waveCrest * sin((2 * M_PI) * _waveCount / width * x + _phase) + height / 2.f)];          continue;                  } else {                    [drawRectObject addLineToPoint:CGPointMake(x, _waveCrest * sin((2 * M_PI) * _waveCount / width * x + _phase) + height / 2.f)];        }      }            [drawRectObject addLineToPoint:CGPointMake(width, height)];      [drawRectObject addLineToPoint:CGPointMake(0, height)];      [drawRectObject addLineToPoint:CGPointMake(0, _waveCrest * sin((2 * M_PI) * _waveCount / width * 0 + _phase) + height / 2.f)];    }];  }    if (self.type & kStrokeWave) {        [self.drawRectObject useDrawingStyle:_strokeStyle drawStrokeBlock:^(DrawRectObject *drawRectObject) {            for (CGFloat x = 0; x <= width; x++) {                if (x == 0) {                    [drawRectObject moveToStartPoint:CGPointMake(x, _waveCrest * sin((2 * M_PI) * _waveCount / width * x + _phase) + height / 2.f)];          continue;                  } else {                    [drawRectObject addLineToPoint:CGPointMake(x, _waveCrest * sin((2 * M_PI) * _waveCount / width * x + _phase) + height / 2.f)];        }      }    }];  }}@end

//// ViewController.m// DrawRectObject//// Created by YouXianMing on 16/7/30.// Copyright © 2016年 YouXianMing. All rights reserved.//#import "ViewController.h"#import "WaveView.h"#import "ReplicatorLineAnimationView.h"#import "UIView+SetRect.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    // Wave 1  {    WaveView *waveView = [[WaveView alloc] initWithFrame:CGRectMake(0, 0, Width, Height)];    waveView.phase   = 0.f;    waveView.waveCrest = 5.f;    waveView.waveCount = 1;    waveView.type   = kStrokeWave | kFillWave;        {      DrawingStyle *fillStyle = [DrawingStyle new];      fillStyle.fillColor   = [DrawingColor colorWithUIColor:[[UIColor redColor] colorWithAlphaComponent:0.25f]];      waveView.fillStyle   = fillStyle;            DrawingStyle *strokeStyle = [DrawingStyle new];      strokeStyle.strokeColor  = [DrawingColor colorWithUIColor:[[UIColor redColor] colorWithAlphaComponent:0.5f]];      strokeStyle.lineWidth   = 0.5f;      waveView.strokeStyle   = strokeStyle;    }        ReplicatorLineAnimationView *replicatorLineView = [[ReplicatorLineAnimationView alloc] initWithFrame:waveView.bounds];    replicatorLineView.direction  = kReplicatorLeft;    replicatorLineView.speed    = 0.1f;    replicatorLineView.contentView = waveView;    [replicatorLineView startAnimation];    [self.view addSubview:replicatorLineView];  }    // Wave 2  {    WaveView *waveView = [[WaveView alloc] initWithFrame:CGRectMake(0, 0, Width, Height)];    waveView.phase   = 0.f;    waveView.waveCrest = 10.f;    waveView.waveCount = 1;    waveView.type   = kStrokeWave | kFillWave;        {      DrawingStyle *fillStyle = [DrawingStyle new];      fillStyle.fillColor   = [DrawingColor colorWithUIColor:[[UIColor redColor] colorWithAlphaComponent:0.5f]];      waveView.fillStyle   = fillStyle;            DrawingStyle *strokeStyle = [DrawingStyle new];      strokeStyle.strokeColor  = [DrawingColor colorWithUIColor:[UIColor redColor]];      strokeStyle.lineWidth   = 0.5f;      waveView.strokeStyle   = strokeStyle;    }        ReplicatorLineAnimationView *replicatorLineView = [[ReplicatorLineAnimationView alloc] initWithFrame:waveView.bounds];    replicatorLineView.direction = kReplicatorLeft;    replicatorLineView.speed   = 0.3f;    replicatorLineView.contentView = waveView;    [replicatorLineView startAnimation];    [self.view addSubview:replicatorLineView];  }    // Wave 3  {    WaveView *waveView = [[WaveView alloc] initWithFrame:CGRectMake(0, 0, Width, Height)];    waveView.phase   = 10.f;    waveView.waveCrest = 15.f;    waveView.waveCount = 1;    waveView.type   = kFillWave;        {      DrawingStyle *fillStyle = [DrawingStyle new];      fillStyle.fillColor   = [DrawingColor colorWithUIColor:[UIColor redColor]];      waveView.fillStyle   = fillStyle;    }        ReplicatorLineAnimationView *replicatorLineView = [[ReplicatorLineAnimationView alloc] initWithFrame:waveView.bounds];    replicatorLineView.direction  = kReplicatorLeft;    replicatorLineView.speed    = 0.5f;    replicatorLineView.contentView = waveView;    [replicatorLineView startAnimation];    [self.view addSubview:replicatorLineView];  }}@end