用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
用drawRect以及CAReplicatorLayer绘制动态水波纹的更多相关文章
- 自定义view实现水波纹效果
水波纹效果: 1.标准正余弦水波纹: 2.非标准圆形液柱水波纹: 虽说都是水波纹,但两者在实现上差异是比较大的,一个通过正余弦函数模拟水波纹效果,另外一个会运用到图像的混合模式(PorterDuffX ...
- Android 自定义view实现水波纹效果
http://blog.csdn.net/tianjian4592/article/details/44222565 在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了 ...
- 用path动画绘制水波纹
用path动画绘制水波纹 效果 源码 // // ViewController.m // PathAnimation // // Created by YouXianMing on 15/7/3. / ...
- 手把手教你画一个 逼格满满圆形水波纹loadingview Android
才没有完结呢o( ̄︶ ̄)n .大家好,这里是番外篇. 拜读了爱哥的博客,又学到不少东西.爱哥曾经说过: 要站在巨人的丁丁上. 那么今天,我们就站在爱哥的丁丁上来学习制作一款自定义view(开个玩笑,爱 ...
- Android -- 贝塞尔实现水波纹动画(划重点!!)
1,昨天看到了一个挺好的ui效果,是使用贝塞尔曲线实现的,就和大家来分享分享,还有,在写博客的时候我经常会把自己在做某种效果时的一些问题给写出来,而不是像很多文章直接就给出了解决方法,这里给大家解释一 ...
- Android特效专辑(一)——水波纹过渡特效(首页)
Android特效专辑(一)--水波纹过渡特效(首页) 也是今天看到的一个特效,感觉挺漂亮的,最近也一直在筹划一个APP,就想把他当做APP的首页,然后加些处理,关于首页APP的特效等我完工了再贴出来 ...
- 适配移动端的在图片上生成水波纹demo
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&q ...
- Android自定义控件-Path之贝赛尔曲线和手势轨迹、水波纹效果
从这篇开始,我将延续androidGraphics系列文章把图片相关的知识给大家讲完,这一篇先稍微进阶一下,给大家把<android Graphics(二):路径及文字>略去的quadTo ...
- 三角函数之美-水波纹载入LoadingView
一.前言 学习是要总结的.近期几天学习了画图相关的,可是使用的机会较少,如今又快要遗忘了,这次看了水波纹的绘制.认为十分有意思,还是 把实现的方法记录下来.技术无他,为手熟尔.还是要多练习,空淡误国, ...
随机推荐
- spfa学习笔记
序 spfa它死了 --by 大佬 但是本蒟蒻还是一如既往的使用spfa... 因为太弱了,其他什么都不会.于是就疯狂开O2跪倒在spfa上. 例题--汽车加油行驶问题 loj跳转链接 luogu跳转 ...
- read命令
read命令从键盘读取变量的值,通常用在shell脚本中与用户进行交互的场合. 该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开.在read命令后面,如果没有指定变量名,读取的数据将被 ...
- 【LOJ】#2509. 「AHOI / HNOI2018」排列
题解 虽然要求一个dfs序,但是不是从根开始贪心 从最小的点开始贪心,最小的点显然是父亲选了之后马上就选它 那么我们每次把最小的点和父亲合并,两个联通块之间也是如此 对于两个联通块,他们合并的顺序应该 ...
- Spring Cache缓存技术的介绍
缓存用于提升系统的性能,特别适用于一些对资源需求比较高的操作.本文介绍如何基于spring boot cache技术,使用caffeine作为具体的缓存实现,对操作的结果进行缓存. demo场景 本d ...
- eclipse launching workspace太慢的解决方法
这几天eclipse调试Android项目的时候反应超慢,右下显示launching workspace就不怎么动了,今天终于卡的受不了了,在网上搜了写方法,设置了下总算好点了,现在把方法贴出来,跟大 ...
- java 获取当前方法名
String _thisMethodName = new Exception().getStackTrace()[0].getMethodName();// 获得当前的方法名
- BZOJ2976 : [Poi2002]出圈游戏
首先模拟一遍得到n个同余方程,然后用扩展欧几里得求出最小的可行解即可,时间复杂度$O(n^2)$. #include<cstdio> #define N 30 int n,i,j,k,x, ...
- bzoj 1455 可并堆+并查集
一个堆和一个并查集对应,并且满足并查集中所有没有死的人等于堆中的人 /************************************************************** Pr ...
- FireDAC 下的 Sqlite [8] - 自定义函数
Sqlite 本身没有这个功能, FireDAC 通过 TFDSQLiteFunction 增加了该功能; 尽管通过某些 SQL 语句或通过视图也可以达到类似效果, 但函数会更灵活些. 本例先建了一个 ...
- DG449 High Voltage Single SPDT Analog Switch in SOT23-8
DESCRIPTION The DG449 is a dual supply single-pole/double-throw (SPDT) switches. On resistance is 38 ...