網站首頁 編程語言 正文
本文實例為大家分享了android實現貝塞爾曲線之波浪效果的具體代碼,供大家參考,具體內容如下
1 前言
為了給我以前的博客填坑,這章講解貝塞爾曲線的幾個常用的應用:
1.波浪效果
2.qq聊天列表上的沾粘體效果
3.翻書頁效果
4.彈性球效果
大家如果把這些看懂并掌握,以后做和貝塞爾曲線相關的效果應該都能信手拈來!
2 波浪效果
原理分析:
其實這個效果應用了2個階的貝塞爾曲線來完成的,先看一下原理分析圖:
有上面的圖可以看出:在屏幕的左面畫出了1.5個波長,在屏幕中畫出1個波長,然后讓它循環的向右移動,這個就會出現波浪效果,這里有幾點需要注意:
1.為什么是1.5個波長而不是1個波長呢?
理論上1個波長就夠了,但是實際運行出來的效果會出現不協調,所以經過調試,我又加了0.5個波長
2.那條綠線是干什么用的?
在波浪線以下的所有空間都要填充成一個顏色,所以path必須是封閉的區間,只有這個才能填充。代碼中我會具體的解釋
我們在編碼的時候只需要計算最左面半個波長的坐標,其他的用for循環搞定。
好了我們看一下代碼:
public class WaveView extends View {
? ? private int ?width = 0;
? ? private int height = 0;
? ? private int baseLine = 0;// 基線,用于控制水位上漲的,這里是寫死了沒動,你可以不斷的設置改變。
? ? private Paint mPaint;
? ? private int waveHeight = 100;// 波浪的最高度
? ? private int waveWidth ?;//波長
? ? private float offset =0f;//偏移量
? ? public WaveView(Context context, AttributeSet attrs) {
? ? ? ? super(context, attrs);
? ? ? ? initView();
? ? }
? ? /**
? ? ?* 不斷的更新偏移量,并且循環。
? ? ?*/
? ? private void updateXControl(){
? ? ? ? //設置一個波長的偏移
? ? ? ? ValueAnimator mAnimator = ValueAnimator.ofFloat(0,waveWidth);
? ? ? ? mAnimator.setInterpolator(new LinearInterpolator());
? ? ? ? mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onAnimationUpdate(ValueAnimator animation) {
? ? ? ? ? ? ? ? float animatorValue = (float)animation.getAnimatedValue() ;
? ? ? ? ? ? ? ? offset = animatorValue;//不斷的設置偏移量,并重畫
? ? ? ? ? ? ? ? postInvalidate();
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? mAnimator.setDuration(1000);
? ? ? ? mAnimator.setRepeatCount(ValueAnimator.INFINITE);
? ? ? ? mAnimator.start();
? ? }
? ? @Override
? ? protected void onDraw(Canvas canvas) {
? ? ? ? super.onDraw(canvas);
? ? ? ? canvas.drawPath(getPath(),mPaint);
? ? }
? ? //初始化paint,沒什么可說的。
? ? private void initView(){
? ? ? ? mPaint = new Paint();
? ? ? ? mPaint.setColor(Color.RED);
? ? ? ? mPaint.setStyle(Paint.Style.FILL);
? ? }
? ? @Override
? ? protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
? ? ? ? super.onLayout(changed, left, top, right, bottom);
? ? ? ? width = getMeasuredWidth();//獲取屏幕寬度
? ? ? ? height = getMeasuredHeight();//獲取屏幕高度
? ? ? ? waveWidth = width;
? ? ? ? baseLine = height/2;
? ? ? ? updateXControl();
? ? }
? ? /**
? ? ?* 核心代碼,計算path
? ? ?* @return
? ? ?*/
? ? private Path ?getPath(){
? ? ? ? int itemWidth = waveWidth/2;//半個波長
? ? ? ? Path mPath = new Path();
? ? ? ? mPath.moveTo(-itemWidth * 3, baseLine);//起始坐標
? ? ? ? //核心的代碼就是這里
? ? ? ? for (int i = -3; i < 2; i++) {
? ? ? ? ? ? int startX = i * itemWidth;
? ? ? ? ? ? mPath.quadTo(
? ? ? ? ? ? ? ? ? ? startX + itemWidth/2 + offset,//控制點的X,(起始點X + itemWidth/2 + offset)
? ? ? ? ? ? ? ? ? ? getWaveHeigh( i ),//控制點的Y
? ? ? ? ? ? ? ? ? ? startX + itemWidth + offset,//結束點的X
? ? ? ? ? ? ? ? ? ? baseLine//結束點的Y
? ? ? ? ? ? );//只需要處理完半個波長,剩下的有for循環自已就添加了。
? ? ? ? }
? ? ? ? //下面這三句話很重要,它是形成了一封閉區間,讓曲線以下的面積填充一種顏色,大家可以把這3句話注釋了看看效果。
? ? ? ? mPath.lineTo(width,height);
? ? ? ? mPath.lineTo(0,height);
? ? ? ? mPath.close();
? ? ? ? return ?mPath;
? ? }
? ? //奇數峰值是正的,偶數峰值是負數
? ? private int getWaveHeigh(int num){
? ? ? ? if(num % 2 == 0){
? ? ? ? ? ? return baseLine + waveHeight;
? ? ? ? }
? ? ? ? return baseLine - waveHeight;
? ? }
}
核心的代碼在 getPath()方法中,其實這個坐標是有規律的:
先找到最左面的半個波長,設置貝塞爾曲線坐標,
然后用for循環,不斷的設置,
這個規律大家體會,我這里簡單提一下。
3 qq聊天列表上的沾粘體效果
先看一個效果圖:
這個做起來小有點復雜。具體思路如下:
1.畫兩個圓,一個黏連小球固定在一個點上,一個氣泡小球跟隨手指的滑動改變坐標。隨著兩個圓間距越來越大,黏連小球半徑越來越小。
2.當間距小于一定值,松開手指氣泡小球會恢復原來位置;
3.當間距超過一定值之后,黏連小球消失,氣泡小球繼續跟隨手指移動,此時手指松開,氣泡小球消失~
結尾
本來想把上面的全部弄在一篇博客呢,現在看來不太可能,一篇一篇的來吧。核心就是貝塞爾曲線的應用,大家如何理解了貝塞爾曲線,這些都不難。
原文鏈接:https://blog.csdn.net/mffandxx/article/details/70891481
相關推薦
- 2022-03-16 淺析ORB、SURF、SIFT特征點提取方法以及ICP匹配方法_C 語言
- 2022-09-03 詳解.NET主流的幾款重量級?ORM框架_實用技巧
- 2023-11-17 python中numpy ndarray 按條件篩選數組,關聯篩選的例子——numpyarray對數
- 2022-11-05 Nginx反向代理location和proxy_pass配置規則詳細總結_nginx
- 2022-06-12 C#集合之有序列表的用法_C#教程
- 2022-05-02 Shell命令中的特殊替換、模式匹配替換、字符串提取和替換的實現_linux shell
- 2022-06-29 python人工智能tensorflow常用激活函數Activation?Functions_pyt
- 2023-05-06 MacOS安裝python報錯"zsh:?command?not?found:python"的解決方
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支