首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Android BezierDemo 源碼深度解析:貝塞爾曲線實現粘連拉伸效果

     編輯:關於C++

本文深入分析 BezierDemo 專案,揭示如何利用二階貝塞爾曲線實現類似 QQ 未讀消息拖拽的「粘連拉伸」動畫效果。

核心類結構

BezierView 繼承 FrameLayout,內部包含:

  • 繪製路徑的 Path 和 Paint。
  • 固定圓中心 (startX, startY)、拖拽圓中心 (x, y)、控制點 (anchorX, anchorY)。
  • 動態半徑 radius,隨距離增大而縮小。
  • 兩個 ImageView:tipImageView(數字提示)、exploredImageView(拉斷後動畫)。

關鍵方法解析

1. calculate() - 幾何計算核心

根據兩圓心距離計算動態半徑:

float distance = sqrt((y-startY)^2 + (x-startX)^2);
radius = -distance/15 + DEFAULT_RADIUS;
if (radius < 9) { isAnimStart = true; /* 觸發拉斷動畫 */ }

計算四邊形四個切點(利用三角函數):

float angle = atan2(y - startY, x - startX);
float offsetX = radius * sin(angle);
float offsetY = radius * cos(angle);
// 四個切點座標
x1 = startX - offsetX; y1 = startY + offsetY;
x2 = x - offsetX;       y2 = y + offsetY;
x3 = x + offsetX;       y3 = y - offsetY;
x4 = startX + offsetX;  y4 = startY - offsetY;

構建閉合路徑(核心):

path.reset();
path.moveTo(x1, y1);
path.quadTo(anchorX, anchorY, x2, y2); // 第一條貝塞爾曲線
path.lineTo(x3, y3);                   // 直線連接
path.quadTo(anchorX, anchorY, x4, y4); // 第二條貝塞爾曲線
path.lineTo(x1, y1);                   // 閉合

精髓:兩條二階貝塞爾曲線共用同一控制點 (anchorX, anchorY),控制點位於兩圓心連線中點。隨手指拖動,控制點移動,曲線內凹形成「橡皮筋」效果。

2. onDraw() - 繪製邏輯

若未拉斷且正在觸摸,調用 calculate() 更新路徑,繪製 path、兩個圓。若已拉斷,播放動畫。

3. onTouchEvent() - 交互處理

記錄手指座標 (x, y),計算控制點 anchor = (start + current) / 2,調用 invalidate() 觸發重繪。處理 ACTION_DOWN 判斷是否點擊提示圖,ACTION_UP/CANCEL 重置狀態。

逐步分解實驗:看清曲線本質

作者通過修改 DEFAULT_RADIUS 放大圓圈、將 Paint.Style 改為 STROKE 顯示線框、隱藏圖片和圓圈僅繪製 Path,直觀展示了路徑由兩條貝塞爾曲線和兩條直線組成的閉合圖形,以及控制點如何「拖住」兩條曲線產生粘連效果。

總結

粘連效果的關鍵:同一個控制點(中間點)「拖住」兩條二階貝塞爾曲線。

動態調整半徑進一步增強真實感。這個 Demo 代碼簡潔,是學習 Android 自定義 View、貝塞爾曲線動畫的絕佳入門案例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved