原理

  • 利用 UIBezierPath + CAShapeLayer 画正弦线
  • 利用 CADisplayLink 重复执行画正弦线
  • 下一次画的正弦线较前一次次平移小段距离,不断重复,就形成了波浪效果(动画效果实现核心)

实现过程

  • 先复习一下正弦函数
/*** *** 正弦波的基础知识  *****  f(x) = Asin(ωx+φ)+k**  A    为振幅, 波在上下振动时的最大偏移**  φ/w  为在x方向平移距离**  k    y轴偏移,即波的振动中心线y坐标与x轴的偏移距离**  2π/ω 即为波长,若波长为屏幕宽度即, SCREEN_W = 2π/ω, ω = 2π/SCREEN_W*/
  • 自定义一个UIView视图,利用UIBezierPath + CAShapeLayer 画正弦线
// 给视图添加ShapeLayer
-(void)starWave {// 设置正弦线的振幅self.waveAmplitude = 0.5 * self.wave_H;// 给视图添加ShapeLayerself.shapeLayer = [CAShapeLayer layer];self.shapeLayer.borderWidth = 1; // 线宽self.shapeLayer.strokeColor = [UIColor redColor].CGColor; // 线的颜色[self.layer addSublayer:self.shapeLayer];[self setShapeLayerPath];}
// 把正弦线加到视图中
- (void)setShapeLayerPath {self.shapeLayer.path = [self sineBezierPath].CGPath;}
// 画正弦线 每次调用sinf函数都确定一个正弦线经过的点
- (UIBezierPath *)sineBezierPath {UIBezierPath *path = [UIBezierPath bezierPath];// 起点[path moveToPoint:CGPointMake(0, self.wave_H * 0.5)];CGFloat y = 0.0f;for (float x = 0.0f; x <= self.wave_W; x++) {// 振幅 A = self.waveAmplitude 为视图的一半// 波长 2π/w = (2 * MP_PI / (2 * M_PI / 200)) = 200 波长为 200// y轴偏移 k = self.wave_H - self.waveAmplitude, 坐标轴起点为左上, k决定正弦线中心线的偏移,振幅变小时正弦线的一直贴着视图最下边y = self.waveAmplitude * sinf((2 * M_PI / 200) * x) + self.wave_H - self.waveAmplitude;[path addLineToPoint:CGPointMake(x, y)];}return path;
}

效果如图:

我们需要的是让正弦图像封闭起来,所以去了边线颜色,加填充颜色, 起点要改为左下,终点改为右下

- (void)starWave {self.shapeLayer.fillColor = [UIColor blueColor].CGColor; // 填充色
}
// 画正弦线
- (UIBezierPath *)sineBezierPath {   [path moveToPoint:CGPointMake(0, self.wave_H)]; // 起始点...[path addLineToPoint:CGPointMake(self.wave_W, self.wave_H)]; // 结束点[path closePath]; // 使封闭return path;
}

效果如图:

  • 利用 CADisplayLink 重复执行画正弦线,配合正弦线偏移让正弦线动起来
-(void)starWave {...//【**波动画关键**】 一秒执行60次(算是CADisplayLink特性),即每一秒执行 setShapeLayerPath 方法60次self.displaylink = [CADisplayLink displayLinkWithTarget:self selector:@selector(setShapeLayerPath)];[self.displaylink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}- (void)setShapeLayerPath {self.offsetX += (self.wave_W / 60); // 正弦线偏移 , 每秒偏移 self.wave_W...
}
- (UIBezierPath *)sineBezierPath {y = self.waveAmplitude * sinf((2 * M_PI / 200) * (x + self.offsetX/*添加偏移*/))+ self.waveAmplitude;
}

效果如图:

  • 结束动画
- (void)stopWave {[self.displaylink invalidate];[self.shapeLayer removeFromSuperlayer];
}

相关demo下载:

https://github.com/Jae-sun/SJUserCenterHeader.git

转载于:https://www.cnblogs.com/jaesun/p/zheng-xian-shui-bo-wen-bo-dong-hua--SJWaveView.html

正弦水波纹波动画 - SJWaveView相关推荐

  1. 2.CCGridAction(3D效果),3D反转特效,凸透镜特效,液体特效,3D翻页特效,水波纹特效,3D晃动的特效,扭曲旋转特效,波动特效,3D波动特效

     1 类图组织 2 实例 CCSprite * spr = CCSprite::create("HelloWorld.png"); spr->setPosition(cc ...

  2. css实现圆球旋像水波波动_手机拍屏幕烦人的“水波纹”小米10靠它给解决掉了...

    相信大家日常用手机拍电视.电脑屏幕,都遇到过"水波纹"(频闪条纹)的现象,十分恼人.那么,"水波纹"到底是啥?它是怎么出现的? 今日,小米官方发文进行了科普,并 ...

  3. 2.CCGridAction(3D效果),3D反转特效,凸透镜特效,液体特效,3D翻页特效,水波纹特效,3D晃动的特效,扭曲旋转特效,波动特效,3D波动特效...

     1 类图组织 2 实例 CCSprite * spr = CCSprite::create("HelloWorld.png"); spr->setPosition(cc ...

  4. css波纹波动效果,CSS 冲击波(水波纹)效果

    实现冲击波--数学知识很重要 *{ margin:0; padding:0; box-sizing:border-box; } html,body{ font-family:"微软雅黑&qu ...

  5. android自定义水波纹,Android自定义View——实现水波纹效果类似剩余流量球(示例代码)...

    最近突然手痒就想搞个贝塞尔曲线做个水波纹效果玩玩,终于功夫不负有心人最后实现了想要的效果,一起来看下吧: 效果图镇楼 一:先一步一步来分解一下实现的过程 需要绘制一个正弦曲线(sin)或者余弦曲线(c ...

  6. 震惊!原来Android OpenGL ES可以这样用,实现 (水波纹)涟漪效果超惊艳!

    用几行代码实现惊艳的特效. 作者:字节流动 链接:https://juejin.im/post/5ed9c9445188254344768bd6 水波纹效果原理 最近一个做视频滤镜的朋友,让我给他做一 ...

  7. android 立体 流量球,Android自定义View——实现水波纹效果类似剩余流量球

    Android自定义View--实现水波纹效果类似剩余流量球 三个点   pre   ber   block   span   初始化   move   理解最近突然手痒就想搞个贝塞尔曲线做个水波纹效 ...

  8. Android自定义View——实现水波纹效果类似剩余流量球

    最近突然手痒就想搞个贝塞尔曲线做个水波纹效果玩玩,终于功夫不负有心人最后实现了想要的效果,一起来看下吧: 效果图镇楼 一:先一步一步来分解一下实现的过程 需要绘制一个正弦曲线(sin)或者余弦曲线(c ...

  9. OpenGL ES 实现动态(水波纹)涟漪效果

    该原创文章首发于微信公众号:字节流动 水波纹效果原理 最近一个做视频滤镜的朋友,让我给他做一个动态水波纹效果,具体就是:点击屏幕上的某一位置,然后波纹以该位置为中心向周围扩散.接到这个需求,一开始就尝 ...

最新文章

  1. win 2003 IIS如何防止代码注入
  2. Java并发编程--ReentrantReadWriteLock
  3. JS 四则运算精度丢失解决方案
  4. js设置全局变量ajax中赋值
  5. 硬件安全 (1) —— SHA-1算法在FPGA上的实现
  6. android p 第三方预装,android P 隐藏API对系统APP的影响
  7. Flowable 数据库表结构 ACT_ID_GROUP
  8. luogu 1344 追查坏牛奶(最小割)
  9. 【clickhouse】ClickHouse表引擎 MergeTree 数据生命周期
  10. mdk系列 Adsl 成功上网指南(非USB ADSL)
  11. Spring 中的事务处理
  12. MySQL外键更新删除设置cascade、set null、restrict、no action的区别
  13. Python学习之波形图
  14. 蠕虫病毒Synaptics.exe感染日记
  15. 云服务器htdocs文件夹在,htdocs文件夹
  16. AD怎么输入坐标_如何把CAD图纸坐标转换成现场坐标?
  17. CCNET的参考文件
  18. Linux开发工具(3)——gcc/g++
  19. java 进阶笔记线程与并发之ForkJoinPool简析
  20. Python爬取微博热搜榜,将数据存入数据库

热门文章

  1. 基于快速GeoHash,如何实现海量商品与商圈的高效匹配?
  2. linux 汇编 读取软盘,Linux下如何格式化软盘和读取软盘?
  3. C#-代码片段的使用(1) 039
  4. Cocos游戏引擎3D特效全新升级 更流畅更炫酷
  5. 基于行为树的新手引导设计
  6. The world at your fingertips — 天涯明月刀幕后23(海战)
  7. 蒋涛,CSDN创始人,俺村的骄傲
  8. oracle 11gR2 RAC root.sh 错误 ORA-15072 ORA-15018
  9. linux系列之-—04 自动删除n天前日志【转】
  10. 好程序员分享Java开发常用规范技巧二