实现弹性组件效果(贝塞尔曲线&&阻尼函数)
来源:互联网 发布:最优化方法 答案 编辑:程序博客网 时间:2024/06/11 17:56
1.贝塞尔曲线
贝塞尔曲线是一种画线的方法,主要是通过四个点确定一条线,首尾两个端点,中间两个点构成一条虚拟的标准线,曲线就根据这条线相切以及两个端点确定。
首先看看如何用贝塞尔曲线画出四分之一个圆:
请先参考这篇博客:http://blog.csdn.net/nibiewuxuanze/article/details/48103059#comments
总结起来,除了首尾两个端点外,中间两个点的位置是由端点和偏移量共同决定的。
如图,B的位置是A向左一个偏移量,C的位置是D向上一个偏移量。而且根据计算这个偏移量是直径/3.6。
2.画一个圆:
为了以后的使用方便,这里用上下左右四个顶点确定一个圆。
重写组件的onDraw方法:
Path path = new Path(); path.moveTo(xA,yA); path.cubicTo(xA+offset,yA,xB,yB-offset,xB,yB); path.cubicTo(xB,yB+offset,xC+offset,yC,xC,yC); path.cubicTo(xC-offset,yC,0,yD+offset,xD,yD); path.cubicTo(0,yD-offset,xA-offset,yA,xA,yA); Paint paint=new Paint(); paint.setAntiAlias(true); paint.setColor(backColor); canvas.drawPath(path,paint);
四个点的位置可以根据半径计算得出。
这里的cubicTo就是用贝塞尔曲线画线的,参数中三个点的位置就是从本位置依次到达的三个点。经过四次贝塞尔画线回到起点,一个圆也就画好了。3.改变顶点的位置:
首先要明白,在圆形的绘制过程中,偏移量是不变的,变的是顶点的位置。所以这里再定义一个变量extra,表示顶点在原位置上移动的距离。右顶点向右移动a,则上下两个顶点也向中间移动a,并向右移动a/2。
至于这个extra是多长,可以自己确定,我用的是半径的二分之一。
加上这个移动量之后,会发现画出的就是一个椭圆了。
4.利用阻尼函数实现动画效果:
动画效果其实就是不断改变extra的值并通知组件重画。可以使用属性动画,这里我直接用了一个子线程。
再定一个一个变量fudu,表示振动的幅度,0到1,乘上extra作为最终应用的移动量。接下来就是对fudu这个值的操作。
为了实现果冻一样的弹性效果,这里用了阻尼函数。
阻尼函数是一个不断振动的函数,我经过笨拙的代数实验取了(0,0.2)这样一个区间进行使用,数值会短暂振动并最终趋于1,由于我最后希望fudu值为0,也就是移动量为0,所以又减了1:
new Thread(new Runnable() { @Override public void run() { while (true){ handler.post(new Runnable() { @Override public void run() { invalidate(); } }); if (x<0.2f){ x+=0.01f; } fudu = (float) (1 - Math.pow(Math.E, -1 * 5 * x) * Math.cos(30 * x)); fudu -=1; if (fudu <0){ fudu =0; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start();
5,30等值都是可以改变的,效果也会有变化。我的效果其实不太好,对阻尼函数更有研究的同志可以教教我。
invalidate用以通知组件进行更新,因为是UI操作所以借助了handler。
完整draw:
@Override protected void onDraw(Canvas canvas) { extra= fudu *radious/2; offset= radious*2/3.6f; xA=radious+extra/2; yA=extra; xB=radious*2+extra; yB=radious; xC=radious+extra/2; yC=radious*2-extra; xD=0; yD=yB; Path path = new Path(); path.moveTo(xA,yA); path.cubicTo(xA+offset,yA,xB,yB-offset,xB,yB); path.cubicTo(xB,yB+offset,xC+offset,yC,xC,yC); path.cubicTo(xC-offset,yC,0,yD+offset,xD,yD); path.cubicTo(0,yD-offset,xA-offset,yA,xA,yA); Paint paint=new Paint(); paint.setAntiAlias(true); paint.setColor(backColor); canvas.drawPath(path,paint); super.onDraw(canvas); }
- 实现弹性组件效果(贝塞尔曲线&&阻尼函数)
- 贝塞尔曲线的艺术---弹性效果实现
- android 实现阻尼效果
- listView实现阻尼效果
- Android自定义View阻尼动画&贝塞尔曲线的实现
- ScrollView实现阻尼回弹效果!
- Android 贝塞尔曲线(一)弹性圆
- Android实现ListView阻尼式(下拉回弹)效果
- 自定义ScrollView实现阻尼效果(类似于QQ下拉一段距离)
- 通过overScrollBy实现下拉视差特效(阻尼效果)
- 阻尼效果
- Android使用最简单的方式实现ListView 拉出回弹效果,阻尼效果(一)
- 弹性ScrollView 上下拉超出后,手指离开后弹回的“阻尼”效果
- Android果冻效果(阻尼动画)
- android 自定义ScrollView实现背景图片伸缩(仿多米,PaPa个人页面特效也称为阻尼效果)
- 自定义控件(24)---自定义控件之setMargins、嵌套ScrollView并且实现ListView阻尼效果
- iOS 贝塞尔曲线实现圆角效果
- 贝塞尔曲线实现球形一变二动画效果
- 递归(2)
- 线程的各种函数
- 使用pyinstaller过程中遇到的一些问题
- DirectFB学习之图形加速驱动的匹配
- 关于char, wchar_t, TCHAR, _T(),L,宏 _T、TEXT,_TEXT、L
- 实现弹性组件效果(贝塞尔曲线&&阻尼函数)
- 蓝桥杯比赛之嵌入式
- 数据结构专项练习(数组、链表、二叉树)
- bzoj1068[SCOI2007]压缩
- 事件冒泡(IE事件流),事件捕获和DOM事件流
- leetcode解题之347. Top K Frequent Elements &451. Sort Characters By Frequency
- HDU 1598 find the most comfortable road
- 解决异常"如果该服务已在当前解决方案中定义,请尝试生成该解决方案,然后再次添加服务引用"
- tushare 获取投资数据