动态

详情 返回 返回

一步一步學習使用FireMonkey動畫(1) 使用動畫組件為窗體添加動態效果 - 动态 详情

FireMonkey提供了一系列的動畫控件,為基於FMX(FireMonkey的簡稱)的應用程序開發提供了較大的靈活性。在VCL上面創建動畫,需要開發人員用一個TTimer組件,然後不斷的移動目標物體的位置,使得目標對象看起來像是動了一樣,這需要編寫大量的控制代碼,而且效果並不是特別理想。

本課將介紹如下的內容:

  1. 使用傳統TTimer創建動畫。
  2. 使用TFloatAnimation通過改變圖片的位置創建動畫。
  3. 使用TPathAnimation創建路徑動畫。

本課是動畫系列的入門篇,在稍後的課時中,會詳細介紹這些動畫組件的具體參數和使用方法。

1. 使用TTimer創建動畫

下面通過一個簡單的例子來演示這種做法:

1. 單擊主菜單中的 File > New > Multi-Device Application - Delphi > Blank Application ,創建一個新的多設備應用程序。

建議立即單擊工具欄上的Save All按鈕,將單元文件保存為Form.Main.pas,將項目保存為Ani_Base.dproj。

項目結構應該像這樣:

img

2. 在工具面板[Palette]中,添加TTimer組件,TImage組件和一個TButton組件。

選中TImage組件,在Object Inspector面板上找到MultiResBitmap屬性,單擊右側的按鈕打開Editing Image1.MultiResBitmap對話框,在彈出的對話框中添加一幅圖片,類似下圖:

img

請繼續在Object Inspector(對象檢查器或屬性面板)上設置這個圖片的Position.X=0;Position.Y=200。

選中按鈕組件,將其Text設置為“TTimer方法”。

3. 接下來,在FormCreate事件中初始化了TTimer控件,然後為TTimer控件的OnTimer事件添加了動畫的代碼,並且在按鈕的單擊事件中啓用了TTimer控件,3個事件處理代碼如下:

procedure TfrmMain.Button1Click(Sender: TObject);
begin
// 切換Timer1的啓用狀態:當Timer1當前為啓用時則禁用,當前為禁用時則啓用
Timer1.Enabled := not Timer1.Enabled;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
// 設置定時器間隔為100毫秒(即每0.1秒觸發一次)
Timer1.Interval := 100;
// 指定定時器的觸發事件處理程序為Timer1Timer
Timer1.OnTimer := Timer1Timer;
// 初始化時禁用定時器
Timer1.Enabled := False;
end;

procedure TfrmMain.Timer1Timer(Sender: TObject);
begin
{ 按菱形路徑順時針移動 }
with Image1.Position do
begin
{ 第一階段:從左下到頂部 }
if (X < 200) and (Y <= 200) then
begin
X := X + 10; // X座標右移10像素
Y := Y - 10; // Y座標上移10像素
end
{ 第二階段:從頂部到右下 }
else if (X >= 200) and (Y < 200) then
begin
X := X + 10; // X座標右移10像素
Y := Y + 10; // Y座標下移10像素
end
{ 第三階段:從右下到底部 }
else if (X > 200) and (Y >= 200) then
begin
X := X - 10; // X座標左移10像素
Y := Y + 10; // Y座標下移10像素
end
{ 第四階段:從底部回退到左下 }
else
begin
X := X - 10; // X座標左移10像素
Y := Y - 10; // Y座標上移10像素
end;
end;
end;

通過四個階段的路徑,模擬了圖片的菱形動畫路徑,運行效果如下所示:

img

現在圖片果然已經按菱形動畫路徑在跳動了。

2. 使用TFloatAnimation創建動畫

3. 在工具面板[Palette]中,添加一個新的TButton組件,指定其Text屬性為“使用TFloatAnimation組件”

接下來選中TImage組件,依次拉3個TFloatAnimation組件到它的下面,也就是TFloatAnimation以TImage組件作為Parent。Structure結構視圖如下所示:

注意:動畫組件並沒有可視化圖標,需要在Structure上進行查看和選擇

img

在這裏可以直接在對象檢查器面板設置這3個TFloatAnimation組件的屬性。由於動畫組件並不會在表單上有一個特定的圖標顯示,需要開發人員在Structure面板上選中動畫,然後在對象檢查器上設置屬性。在這裏將使用代碼方式列出參數值,以便於設置。

4. 為Button2添加如下的代碼,初始化並且運行動畫組件。

procedure TfrmMain.Button2Click(Sender: TObject);
begin
// 配置X軸平移動畫 (FloatAnimation1)
FloatAnimation1.PropertyName := 'Position.X'; // 設置動畫目標屬性為X座標
FloatAnimation1.StartFromCurrent := True; // 從當前位置開始動畫
FloatAnimation1.StopValue := Image1.Position.X + 400; // 設置X軸終點值:當前位置向右400像素
FloatAnimation1.Duration := 4; // 設置動畫持續時間為4秒
FloatAnimation1.Loop := True; // 設置動畫循環播放
FloatAnimation1.AutoReverse := True; // 設置動畫自動反向(往復運動)

// 配置Y軸向上移動動畫 (FloatAnimation2) - 初始垂直移動
FloatAnimation2.PropertyName := 'Position.Y'; // 設置動畫目標屬性為Y座標
FloatAnimation2.StartFromCurrent := True; // 從當前位置開始動畫
FloatAnimation2.StopValue := Image1.Position.Y - 200; // 設置Y軸終點值:當前位置向上200像素
FloatAnimation2.Duration := 2; // 設置動畫持續時間為2秒

// 配置Y軸往復運動動畫 (FloatAnimation3) - 後續垂直振盪
FloatAnimation3.PropertyName := 'Position.Y'; // 設置動畫目標屬性為Y座標
FloatAnimation3.StartFromCurrent := True; // 從當前位置開始動畫
FloatAnimation3.StopValue := Image1.Position.Y + 200; // 設置Y軸終點值:當前位置向下200像素
FloatAnimation3.Duration := 4; // 設置動畫持續時間為4秒
FloatAnimation3.Loop := True; // 設置動畫循環播放
FloatAnimation3.AutoReverse := True; // 設置動畫自動反向(往復運動)

// 檢查X軸動畫是否已在運行,避免重複啓動
if not FloatAnimation1.Running then
begin
FloatAnimation1.Start; // 啓動X軸往復平移動畫
FloatAnimation2.Start; // 啓動Y軸向上移動動畫
// 注意:FloatAnimation3不會立即啓動,將在FloatAnimation2完成後由FloatAnimation2Finish事件觸發
end;
end;

procedure TfrmMain.FloatAnimation2Finish(Sender: TObject);
begin
// FloatAnimation2動畫完成時的回調事件
// 當向上移動動畫完成後,啓動垂直方向的往復振盪動畫
FloatAnimation3.Start; // 啓動Y軸往復運動動畫(上下振盪)
end;

當用户點擊 Button2 按鈕時,Image1 會開始執行一系列動畫:

  1. 立即開始:在 水平方向(X軸) 上進行持續的左右往復移動(像鐘擺)。

  2. 立即開始:在 垂直方向(Y軸) 上先向上移動一段距離。

  3. 隨後開始:待向上的移動完成後,在 垂直方向(Y軸) 上轉變為持續的上下往復移動(像彈跳)。

  4. 最終,Image1 會一邊左右搖擺,一邊上下彈跳,形成一個非常動態的菱形動畫視覺效果。

img

如果與TTimer生成的動畫進行比較,可以看到這裏的動畫要順滑很多。

3. 使用TPathAnimation創建動畫

5. 選中Image1控件,然後從工具欄拖一個TPathAnimation控件到其上面,使之成為Image1的子組件。

img

然後添加一個按鈕,其Text屬性設置為“使用TPathAnimation組件”,為其添加如下的事件處理代碼:

// 主窗體中 Button3 的點擊事件處理過程
procedure TfrmMain.Button3Click(Sender: TObject);
begin
  // 設置路徑動畫的路徑
  // 首先將路徑的起始點移動到座標原點 (0, 0)
  PathAnimation1.Path.MoveTo(PointF(0, 0));
  
  // 從當前點繪製直線到座標 (200, -200)
  PathAnimation1.Path.LineTo(PointF(200, -200));
  
  // 從當前點繼續繪製直線到座標 (400, 0)
  PathAnimation1.Path.LineTo(PointF(400, 0));
  
  // 從當前點繼續繪製直線到座標 (200, 200)
  PathAnimation1.Path.LineTo(PointF(200, 200));
  
  // 閉合路徑:從當前點繪製直線回起始點,形成封閉圖形
  PathAnimation1.Path.ClosePath;
  
  // 設置動畫循環播放屬性為 True,動畫將無限循環
  PathAnimation1.Loop := True;
  
  // 設置動畫完成一次完整路徑所需的時間為 8 秒
  PathAnimation1.Duration := 8;

  // 啓動路徑動畫
  PathAnimation1.Start;
end;

上面的代碼首先構建了一條封閉的路徑,然後TImage會沿着這條路徑來移動位置,形成動畫效果。

img

可以看到,它實現了類似前是面2種的動畫效果。

總結

傳統的TTimer模式的動畫,需要程序員控制動畫的具體位置,對於複雜的動畫,往往需要編寫大量的代碼。由於所有邏輯和UI更新都在OnTimer事件中完成,如果計算複雜會直接阻塞UI。

FireMonkey(以後簡稱FMX)提供的動畫組件具有如下的優勢:

  • 可以在設計時進行動畫的配置,動畫間隔由FireMonkey的渲染管線和計時器統一管理,通常利用GPU進行平滑渲染。
  • 動畫的進度由內部高精度時鐘控制,與持續時間(Duration)嚴格綁定,幀率是自適應的。
  • 動畫引擎在後台處理所有計算,並通過安全的方式更新UI,開發者無需關心線程問題。
  • 內置插值(Inverse, Circular, Elastic等)、自動反轉、循環、路徑跟隨等高級功能。

FMX除了提供豐富的動畫組件外,還在TFmxObject對象中整合了動畫函數,使得FireMonkey可以創造出非常豐富的動畫效果的軟件。

接下來會通過幾節內容詳細介紹這些動畫組件的具體使用方法。

Add a new 评论

Some HTML is okay.