動態

詳情 返回 返回

一步一步學習使用FireMonkey動畫(4) 使用Delphi的基本動畫組件類,路徑和位圖列表動畫 彈跳小球和奔跑的小人示例 - 動態 詳情

在《一步一步學習使用FireMonkey動畫(3)》中,介紹了TAnimation的多數子類,本節將對TRectAnimation、TPathAnimation和TBitmapListAnimation這3個子類進行介紹。

本節將介紹的主題如下:

  1. 使用TPathAnimation創建路徑跟隨的小球。
  2. 使用TBitmapListAnimation打造奔跑的小人動畫
  3. 使用TRectAnimation打造內外邊距移動動畫

1. 使用TPathAnimation創建路徑動畫

TPathAnimation動畫允許我們將目標控件沿一段矢量路徑進行動畫。在本系列的《一步一步學習使用FireMonkey動畫(1)》中,演示瞭如何使用TPathAnimation的Path屬性進行路徑的繪製,例如類傳如下的代碼:

  PathAnimation1.Path.MoveTo(PointF(0, 0));

TPathAnimation 並不從 TCustomPropertyAnimation 繼承,儘管它處理了目標對象的一些屬性。處理的屬性( Position 和 RotationAngle )只是硬編碼到動畫對象中。

TPathAnimation的Path屬性接收矢量圖形數據,可以在網站上找一些svg的矢量素材來使用,比如:

https://www.svgviewer.dev/

這個網站提供了很多的素材,可以複製Path路徑中的路徑數據,如下圖所示:

img

下面以TPath組件為例,它的Path屬性與TPathAnimation類似,它提供了一個可視化的編輯器,可以實時的查看矢量路徑。

img

還可以使用svg編輯工具,比如InkScape,它完全免費且開源,可以在如下的網址下載:

https://inkscape.org/

可以使用這個工具繪製矢量圖形,導出為svg格式的文件,這個文件是一個XML格式的文件,用記事本打開,複製其中的矢量路徑到TPath或TPathAnimation的Path屬性即可。

比如我在InkSacpe中使用鋼筆工具隨便畫了一段線條:

接下來將其導出為svg文件,用記事本打開這個文件,將其d部分的屬性值拷貝到TPath的Data屬性中:

img

這樣成功的得到了一條路徑。

注意:FireMonkey 支持通過多個組件(如 TPath 、 TPath3D 和 TLabelPath )使用可縮放矢量圖形(SVG)。這些組件都使用一個內部數據結構( TPathData ,定義在 FMX.Graphics 中),該結構可以解析和使用來自 SVG 定義的圖形數據。

接下來新建一個Multi Deivce應用程序,使用空白模板,在主窗體上放一個TPath,然後將我們在《一步一步學習使用FireMonkey動畫(3)》中創建的彈跳小球複製到本項目中。為彈跳小球添加一個TPathAnimation動畫。

Structure結構如下所示:

img

分別為TPathAnimation的Path屬性以及TPath的Data屬性指定如下的路徑數據:

M3.84500002861023,3.47300004959106 C4.83799982070923,24.6110000610352 26.2040004730225,34.9749984741211 42.875,30.8320007324219 C69.8730010986328,24.121000289917 82.1620025634766,-9.76099967956543 74.6009979248047,-37.4169998168945 C63.992000579834,-76.2160034179688 23.7210006713867,-93.3140029907227 -9.33600044250488,-80.4909973144531 C-52.2709999084473,-63.8380012512207 -70.8339996337891,-8.08600044250488 -55.2200012207031,37.6059989929199 C-35.9000015258789,94.1429977416992 24.3759994506836,118.28099822998 73.6240005493164,96.3960037231445 C132.567993164063,70.2020034790039 157.505996704102,-7.92000007629395 133.664993286133,-71.5500030517578 C105.81600189209,-145.880996704102 25.3040008544922,-177.113998413086 -40.0859985351563,-146.054992675781 C-95.6880035400391,-119.646003723145 -129.975997924805,-55.0750007629395 -127.064002990723,11.4790000915527

Path Designer窗口如下所示:

img

最後,在屬性面板設置TPathAnimation動畫屬性:

img

除了AnimationType和Interpolation暫時還未詳細介紹外,這裏還有一個Rotate屬性,該屬性的意思是:

指定動畫過程中對象是否旋轉。使用 Rotate 屬性可設定父控件在動畫期間是否進行旋轉。若將 Rotate 設置為 True,控件將進行旋轉:正向動畫時控件底部朝向路徑方向,反向動畫時控件頂部朝向路徑方向。

運行動畫,可以看到彈跳小球已經按照路徑在運動。

img

仔細觀察可以看到小球實際上是在旋轉的。

最後來一個畫蛇添足,為小球的運動添加一些軌跡,這裏需要響應TPathAnimation的OnProcess事件,這個事件在每一次動畫間隔(也就是每一幀刷新時)需要刷新動畫顯示時觸發。

private
    { Private declarations }
    FDotPosition:TPointF; // 聲明一個私有字段,用於存儲上一次記錄的點位置(TPointF類型,包含X和Y座標)
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.fmx}

procedure TfrmMain.PathAnimation1Process(Sender: TObject);
const CircleSize = 4; // 定義常量,表示繪製圓點的大小
begin
  if FDotPosition.Distance(CircleBall.Position.Point) > CircleSize then // 判斷當前球位置與上次記錄點之間的距離是否大於圓點尺寸
  begin
    FDotPosition := CircleBall.Position.Point/2; // 計算新位置:將球當前位置座標除以2(可能是為了縮小軌跡)
    var LDot := TCircle.Create(Self); // 動態創建一個圓形控件(TCircle實例)
    try
      LDot.Parent := Self; // 設置圓形的父容器為當前窗體,使其顯示在窗體上
      LDot.Height := CircleSize; // 設置圓形的高度為預設的圓點尺寸
      LDot.Width := CircleSize; // 設置圓形的寬度為預設的圓點尺寸
      LDot.Position.Point := FDotPosition; // 將圓形定位到計算得到的新座標位置
      LDot.Position.Point.Offset(-CircleSize/2,-CircleSize/2); // 調整位置:將圓心偏移(-半徑值),使繪製點以中心為基準(通常用於居中顯示)
    except
      LDOt.Free; // 異常處理:如果創建或設置過程中發生錯誤,則釋放已創建的圓形對象
    end;
  end;
end;

這樣當彈跳小球沿路徑運動時,會顯示一個軌跡:

img

通過這個軌跡,可以發現,每一次動畫的刷新時間似乎並不固定,這是由於不同的插值設置所影響的。

在後續的內容中會介紹動畫的一些屬性和事件的作用,敬請關注。

2. 使用TBitmapListAnimation打造奔跑的小人動畫

這個控件讓我們可以將一系列的連續的靜態圖片動起來,比如有下面的一幅圖片:

img

TBitmapListAnimation通過將多個動畫幀組合在一個圖像條帶中,然後按順序快速切換這些幀來實現動畫播放,非常適合處理那些不適合用矢量路徑或屬性插值實現的複雜動畫(例如角色動畫、特效等)。

它具有如下的一些新的屬性:

  • AnimationBitmap 設置源圖像,包含所有動畫幀的長條帶狀位圖。
  • AnimationCount 指定動畫的總幀數。
  • AnimationRowCount 指定源圖像中動畫的行數,常用於打包多組動畫。
  • PropertyName 指定要動畫化的目標屬性,對於序列幀動畫,這通常是 Bitmap。

上面的圖中,一共有5行圖片,總共是30幀。

下面拉一個TRectangle控件到窗體,然後放一個TBitmapListAnimation在其上面,使TBitmapListAnimation的Parent指向TRectangle。

為TBitmapListAnimation的AnimationBitmap指定上面的圖片,設置 AnimationCount為30,AnimationRowCount為5。

img

現在運行這個示例,可以看到小人已經在奔跑了。

img

是不是有一些電影小視頻的效果了。

3. 使用TRectAnimation創建內外邊距動畫。

RectAnimation 是為了處理 FMX 視覺對象的 Padding 和 Margins 屬性而引入的常見情況。這裏涉及到的數據結構是 TBounds (定義在 FMX.Types 單元中),它是 FMX 中邊距和填充的實際類型。

  • Padding:是指控件的內邊距,是控件邊緣和內部的子元素之間的距離。
  • Margins:是指控件的外邊距,是控件的外邊緣和其容器的邊緣之間的距離。

img

它們均為TBound類型,具有Left、Top、Bottom、Right 4個屬性,通過使用TRectAnimation,則可以創建內外邊距的移動效果。

請在主窗體上拖一個TRectangle控件,拖一個TRectAnimation以它作為父項,在其內部再放一個TRectangle,指定其Align為Client,佔滿整個矩形。

為TRectAnimation設置如下的屬性:

      AnimationType = InOut
      AutoReverse = True
      Enabled = True
      Duration = 2
      Interpolation = Exponential
      Loop = True
      PropertyName = 'Padding'
      StopValue.Left = 50
      StopValue.Top = 50
      StopValue.Right = 50
      StopValue.Bottom = 50

這裏StartValue保持了默認的全是0,StopValue全部設置為50,PropertyName只能選擇Margins和Padding,這裏選擇了Margins,現在運行動畫,可以看到內邊距果然產生了動畫效果。

img

總結

本章介紹了3個有意思也是特別有創意的控件,一個是矢量路徑動畫TPathAnimation,一個是位圖動畫控件TBitmapListAnimation,還有一個內外邊距變化的TRectAnimation控件,它們都可以創造出令人驚歎的動畫效果。對於程序員來説,可能並不缺動畫工具,而是缺那麼一絲絲創意了。

Add a new 評論

Some HTML is okay.