前言

最近工作上比较忙碌,很久没有更新文章了,难得国庆小长假,现在是2019年10月2日凌晨00:49,写一篇简单且实用的贝塞尔曲线应用,许多技术点的文章很多前辈都已经写的很好了,所以 如有纰漏之处,欢迎留言指正,同时也欢迎各位留言需要的技术点类型,争取奉献更优质的技术文章。

贝塞尔曲线简介

千篇一律,很多类似的文章都会介绍一下什么是贝塞尔曲线,但是我这里就不做介绍了,原因有二,其一 正如上述所说许多类似的文章都已经介绍过了,其二 贝塞尔曲线只是一个公式,如果我介绍也是借用官方的图片展示一下贝塞尔曲线的效果而已。所以我们在这里只需要知道在Android API为我们提供了绘制二阶贝塞尔曲线和三阶贝塞尔曲线的方法即可。

效果图

本文,最终实现效果如图所示:

从图中我们可以看出,水纹不断波动并且上涨,当上涨超过屏幕时,自动最初高度波动,接下来,我们就来看如何实现这一效果。

实现过程

  • 所需要知道的

Android API为我们提供了绘制二阶贝塞尔曲线和三阶贝塞尔曲线的方法

绘制二阶贝塞尔曲线的方法是:

/*** Same as quadTo, but the coordinates are considered relative to the last* point on this contour. If there is no previous point, then a moveTo(0,0)* is inserted automatically.** @param dx1 The amount to add to the x-coordinate of the last point on*            this contour, for the control point of a quadratic curve* @param dy1 The amount to add to the y-coordinate of the last point on*            this contour, for the control point of a quadratic curve* @param dx2 The amount to add to the x-coordinate of the last point on*            this contour, for the end point of a quadratic curve* @param dy2 The amount to add to the y-coordinate of the last point on*            this contour, for the end point of a quadratic curve*/
public void rQuadTo(float dx1, float dy1, float dx2, float dy2) {isSimplePath = false;nRQuadTo(mNativePath, dx1, dy1, dx2, dy2);
}

从源码注释中我们可以看出rQuadTo传递的参数分别是第一个点与第二个点距离上一个点的相对X坐标,相对Y坐标

quadTo方法传递的是绝对坐标(如下所示)

/*** Add a quadratic bezier from the last point, approaching control point* (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for* this contour, the first point is automatically set to (0,0).** @param x1 The x-coordinate of the control point on a quadratic curve* @param y1 The y-coordinate of the control point on a quadratic curve* @param x2 The x-coordinate of the end point on a quadratic curve* @param y2 The y-coordinate of the end point on a quadratic curve*/
public void quadTo(float x1, float y1, float x2, float y2) {isSimplePath = false;nQuadTo(mNativePath, x1, y1, x2, y2);
}

三阶贝塞尔曲线与二阶类似分别是:

cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)

rCubicTo(float x1, float y1, float x2, float y2,float x3, float y3)
  • 新建WaveRippleView继承自View

既然要绘制,那么肯定要初始化画笔和路径,画笔的颜色值选择蓝色尽可能和海水颜色相似,画笔设为封闭样式

/*** 初始化* @param context*/
private void init(Context context) {paint = new Paint();paint.setColor(Color.parseColor("#009FCC"));paint.setStyle(Paint.Style.FILL);path = new Path();
}
  • 如何绘制水波纹

好吧,对不起观众的地方来了,我实在找不到一种好的画图软件可以代替手工随心所欲的画,要么就是鼠标操作太费劲,要么就是不能达到想要的效果。

矩形表示手机屏幕(这个自定义view默认是充满屏幕的),波浪线表示水纹波动效果。

一段水波纹是曲线AD,我们只需要让这段曲线不断的滚动就实现了水波纹动画。曲线AD我们可以用贝塞尔曲线分别画出曲线AC和曲线CD,我们之所以从屏幕外开始画是因为水波纹要不断的波动要确保任何时刻都能看到水波纹,所以我们需要在屏幕前后及屏幕内画满水波纹。

设置水波纹的高度WAVE_HEGHT为100,曲线AD的长度即水波纹的波长WAVE_LENGTH为1500(具体值根据显示效果修改)

设置起始点Y点wavestartY为400;

/*** 波纹的长度*/
private final static int WAVE_LENGTH = 1500;/*** 波纹的高度*/
private final static int WAVE_HEGHT = 100;/***  起始点y坐标*/
private static int wavestartY = 400;
  • 计算ABCD点坐标

绘制AD曲线,最主要的是计算ABCD的坐标,根据我们的定义不难得出

A点坐标为(-WAVE_LENGTH,wavestartY)

B点相对A点坐标为(WAVE_LENGTH / 4, -WAVE_HEGHT)

C点相对B点坐标为(WAVE_LENGTH / 2, 0)

以此类推:

path.moveTo(-WAVE_LENGTH+dx, wavestartY);
for (int i = -WAVE_LENGTH; i < getWidth() + WAVE_LENGTH; i = i + WAVE_LENGTH) {path.rQuadTo(WAVE_LENGTH / 4, -WAVE_HEGHT, WAVE_LENGTH / 2, 0);path.rQuadTo(WAVE_LENGTH / 4, WAVE_HEGHT, WAVE_LENGTH / 2, 0);
}
canvas.drawPath(path, paint);

此时运行代码,效果如图所示:

此时我们的看到AD曲线绘制回来了,为了看起来更像水纹波动,还需要将D点和A点之间下方的空隙连接起来

path.lineTo(getWidth(), getHeight());
path.lineTo(0,getHeight());
path.close();

连接起来后,运行效果如图所示:

此时看起来就比较像水纹了

  • 让水纹波动

水纹波其实就是一个简单的属性动画,关于动画我们这里不详细介绍了,可移步至我之前的文章

/*** 水波纹属性动画*/
public void startAnim(){final ValueAnimator valueAnimator = ValueAnimator.ofInt(0,WAVE_LENGTH);valueAnimator.setDuration(2500);valueAnimator.setRepeatCount(ValueAnimator.INFINITE);valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {dx = (int) valueAnimator.getAnimatedValue();postInvalidate();}});valueAnimator.start();
}

这里记得设置动画插值器让动画看起来更加流畅。

动画每执行一次就重新绘制一次,需要注意的是绘制的起点变为

path.moveTo(-WAVE_LENGTH+dx, wavestartY);

执行动画,运行效果如图所示:

  • 水波纹升涨

最后我们让水波纹升涨就大功告成了,水波纹升涨只是绘制时y起点升高,所以我们让绘制的起点每次绘制时都减少一个像素

当值小于0的时候,重新设置为初始值400即可

wavestartY = wavestartY - 1;
if (wavestartY <= 0){wavestartY = 400;
}
path.moveTo(-WAVE_LENGTH+dx, wavestartY)

代码比较简单就不贴全部代码了,需要的留言邮箱即可。

写在最后

如有纰漏之处,欢迎指正。记得点赞+关注哦!

Android 贝塞尔曲线实现水纹波动效果相关推荐

  1. android 贝塞尔曲线 波浪线,Android 贝塞尔曲线实现水纹波动效果

    贝塞尔曲线简介 千篇一律,很多类似的文章都会介绍一下什么是贝塞尔曲线,但是这里就不做介绍了,我们在这里只需要知道在Android API为我们提供了绘制二阶贝塞尔曲线和三阶贝塞尔曲线的方法即可. 效果 ...

  2. android动态波浪效果,android贝塞尔曲线实现波浪效果

    本文实例为大家分享了android贝塞尔曲线实现波浪效果的具体代码,供大家参考,具体内容如下 因为手机录制gif不知道下什么软件好,所以暂时就先忽略效果图了 我在屏幕外多画了1.5个波浪,延伸至屏幕内 ...

  3. android波浪动画简书,Android贝塞尔曲线————波浪效果(大波浪)

    Hello大家好,很高兴又一次与大家见面,今天是农历丁酉鸡年(大年初四),现在跟大家拜年有点晚,算是拜晚年,祝大家晚年幸福. 这么快大伙都到了晚年了,Android贝塞尔曲线我也准备以一个大波浪来结束 ...

  4. Android利用贝塞尔曲线实现翻书效果(适配AndroidX)

    实现背景 不知道你有没有遇到同样的问题,要实现翻书效果,如果你是使用github上的demo或者好多博客上写的方式,你会发现,当api从28开始,会抛出Invalid Region.Op.REPLAC ...

  5. Android 贝塞尔曲线——类似QQ红点拖拽效果

    在Android绘制中,提供了更为丰富绘制api--Path类,包括直线,二阶贝塞尔曲线,三阶贝塞尔曲线,弧形,圆,椭圆,圆角矩形等等,path的绘制最终是调用了C中的绘制方法. 下面来看一下常用的几 ...

  6. Android 贝塞尔曲线实战之网易云音乐鲸云特效,2021程序员进阶宝典

    一阶这个比较简单,因为没有在网上找到可以直接输入数学公式的工具,就手工推导了下. ![在这里插入图片描述](https://img- <Android学习笔记总结+最新移动架构视频+大厂安卓面试 ...

  7. Android 贝塞尔曲线实战之网易云音乐鲸云特效,apm性能监控系统

    小说阅读 APP 的翻页效果. 简介 ===================================================================== 在开始实战之前,我们还 ...

  8. Android 贝塞尔曲线实战之网易云音乐鲸云特效

    作者:哈哈将 -个推 Android 高级开发工程师 前言 APP开发市场已经告别"野蛮生长"时代,人们不再满足于APP外形创新,而将目光转向全方面的用户体验上.在这过程中,动效化 ...

  9. android贝塞尔曲线,一文解析 Android 贝塞尔曲线

    原标题:一文解析 Android 贝塞尔曲线 相信很多同学都知道"贝塞尔曲线"这个词,我们在很多地方都能经常看到.利用"贝塞尔曲线"可以做出很多好看的UI效果, ...

最新文章

  1. java同步与死锁_Java多线程 - 线程同步与死锁
  2. SPOJ - BITDIFF: Bit Difference [神妙の预处理]
  3. Splunk安装和配置及源码编译安装SVN
  4. Linux远程软件xshell的使用
  5. CNDO-INTGRL-SS-BINTGS-斯莱特轨道指数--- 精确方法
  6. python shelve模块_python常用模块之shelve模块
  7. Nginx部署及综合应用
  8. mybatis+spring报错PropertyAccessException 1
  9. android开发工具下载
  10. 深入::first-letter的研究
  11. sqlalchemy与mysql映射
  12. vs查询mysql返回数据_vs与数据库连接查询
  13. 关于 Matlab R2014a下载与安装流程
  14. 移动广告聚合平台经验分享:芒果、果合、Adview、抓猫哪家好?
  15. 红帽Linux登录密码忘了,redhat linux忘记登陆密码之解决办法
  16. 软件工程中的数据流图
  17. OC中内存管理(转)
  18. 视频演示-Snapper快捷优秀的音频预览播放器演示
  19. OpenCat 简评
  20. 桌面计算机未响应怎么办,电脑桌面假死(点击无反应)怎么解决?试试这三种处理方法吧...

热门文章

  1. 【简单思考】jzxx奖牌整理
  2. svn 冲突解决办法
  3. 改计算机名后ansys打不开,更改计算机名后 Ansys重新注册简单办法 20140611.pdf
  4. 【30天学会接口自动化测试】接口自动化测试之实际项目做接口测试(6)
  5. 智能压力测试垫时刻监测我们的健康,使我们的生命得到保障-新导智能
  6. 小米商城静态页面导航图
  7. 免费的webservice接口
  8. 数字IC手撕代码-泰凌微笔试真题
  9. c语言怎么比较两个字母大小,C语言strcmp()函数:比较两个字符串的大小
  10. micropython驱动sh1106点亮oled