瞭解如何藉由變更 UI 中元素的相對座標系統,在 Windows Runtime API 中使用轉換功能。 這可用來調整個別 XAML 元素的外觀,例如縮放、旋轉或轉換 x-y 空間中的位置。
什麼是轉換?
轉換 定義了如何將一個座標空間的點映射或轉換到另一個座標空間。 當轉換套用至UI元素時,它會變更該UI元素在UI中轉譯至畫面的方式。
想想四種廣泛的分類中的轉換:翻譯、旋轉、縮放和扭曲(或剪力)。 為了使用圖形 API 來變更 UI 元素的外觀,通常最簡單的方法是創建每次只定義一個操作的轉換。 因此,Windows 執行時間會為每個轉換分類定義離散類別:
- TranslateTransform:藉由設定 X 和 Y的值,來平移 x-y 空間中的元素。
- ScaleTransform:藉由設定一個中心點並設置 CenterX、CenterY、ScaleX 及 ScaleY的值來縮放轉換。
- RotateTransform:藉由設定 Angle、 CenterX 和 CenterY 的值,以 x-y 空間旋轉。
- SkewTransform:通過設定 AngleX、AngleY、CenterX 和 CenterY的值,在 x-y 空間中實現傾斜或剪切。
在這些案例中,您可能最常針對UI案例使用 TranslateTransform 和 ScaleTransform 。
您可以合併轉換,而有兩個 Windows 執行階段類別支援這一點:CompositeTransform 和 TransformGroup。 在 CompositeTransform中,轉換會依下列順序套用:「縮放」、「扭曲」、「旋轉」、「平移」。 如果您想要以不同的順序套用轉換,請使用 TransformGroup 而非 CompositeTransform 。 如需詳細資訊,請參閱 CompositeTransform。
轉換和佈局
在 XAML 配置中,轉換會在版面配置階段完成之後套用,因此在套用轉換之前,已進行可用空間計算和其他配置決策。 因為佈局優先,如果您轉換位於 網格的元素或 儲存格,或在佈局過程中分配空間的類似佈局容器中的元素,您有時會得到非預期的結果。 轉換的元素可能會顯示為截斷或遮蔽,因為它試圖繪製到在父容器內分割空間時沒有計算轉換後尺寸的區域。 您可能需要實驗轉換結果,並調整一些設定。 例如,您可能需要變更 中心 屬性或直接指定版面配置空間的固定像素測量值,以確保父項目配置足夠的空間,而不是依賴自適應版面配置和星號大小調整。
移轉注意事項: Windows Presentation Foundation (WPF) 具有在版面配置階段之前應用轉換的 LayoutTransform 屬性。 但 Windows 執行時間 XAML 不支援 LayoutTransform 屬性。 (Microsoft西爾弗萊特也沒有這個屬性。
小提示
作為替代方案,Windows 社群工具組提供 LayoutTransformControl,讓您可以將矩陣轉換套用到應用程式中的任何 FrameworkElement。
將變換套用至 UI 元素
當您將轉換套用至物件時,通常會執行此動作來設定屬性 UIElement.RenderTransform。 設定此屬性並不會逐像素地改變物件。 屬性真正執行的動作是在該物件所在的本地座標空間內套用轉換。 然後,渲染邏輯和操作(佈局後)會渲染合併的座標空間,這樣看起來物件的外觀似乎已經改變,也可能改變其佈局位置(如果套用了 TranslateTransform)。
根據預設,每個呈現轉換都會置中於目標物件本地座標系統的原點,即 (0,0)。 唯一的例外狀況是 TranslateTransform,它沒有要設定的中心屬性,因為翻譯效果是相同的,無論其置中位置為何。 但另一個轉換各有屬性,這些屬性會設定 CenterX 和 CenterY 值。
每當您使用轉換與 UIElement.RenderTransform時,請記住,在 UIElement 上有另一個屬性會影響轉換的行為:這個屬性是 RenderTransformOrigin。 RenderTransformOrigin 所宣告的,是整個轉換應該套用至元素的預設(0,0)點,還是套用至該元素相對座標空間內的其他某個原點。 對於一般元素,[0,0] 會將轉換放在左上角。 依您想要達到的效果而定,您可能會選擇變更 RenderTransformOrigin,而不是調整變換上的 CenterX 和 CenterY 值。 請注意,如果您同時套用 RenderTransformOrigin 和 CenterX / CenterY 值,結果可能會相當令人困惑,特別是如果您要讓任何值產生動畫效果。
為了碰撞檢測的目的,應用變換的對象將繼續以預期的方式響應輸入,從而保持其在 x-y 空間中的視覺外觀一致。 例如,如果您在 UI 中使用 TranslateTransform 將 Rectangle 橫向移動了 400 像素,當使用者按下 Rectangle 出現的點時,Rectangle 會回應 PointerPressed 事件。 在使用者按下 矩形 移動前的區域時,不會收到錯誤事件。 對於影響命中測試的任何 z 索引考慮,套用轉換並不會有影響,決定哪個元素處理 x-y 空間中點輸入事件的 z-index 仍會根據容器中宣告的子元素順序進行評估。 這個順序通常與您在 XAML 中宣告元素的順序相同,不過對於 Canvas 物件的子元素,您可以將 Canvas.ZIndex 附加屬性套用至子元素來調整順序。
其他轉換屬性
- Brush.Transform、Brush.RelativeTransform:這些會影響 Brush 在套用 Brush 區域內的座標空間來設定視覺屬性,例如前景和背景。 這些轉換與最常見的筆刷無關(通常是使用 SolidColorBrush 設定純色),但在使用 ImageBrush 或 LinearGradientBrush 繪製區域時,可能偶爾會很有用。
- Geometry.Transform:您可以使用此屬性,先將轉換套用至幾何體,然後再使用該幾何體作為 Path.Data 屬性值。
轉換之動畫制作
轉換 物件可以動畫化。 若要對 轉換執行動畫,請將相容類型的動畫套用至您想要執行動畫的屬性。 這通常表示您使用 DoubleAnimation 或 DoubleAnimationUsingKeyFrames 物件來定義動畫,因為所有的轉換屬性都是 Double 類型。 影響用於 UIElement.RenderTransform 值之轉換的動畫,即使持續時間非零,也不被視為相依動畫。 如需相依動畫的詳細資訊,請參閱 分鏡腳本動畫。
如果您以動畫顯示屬性來產生與最終視覺外觀類似的轉換效果,例如,以動畫顯示 Width 和 Height 的 FrameworkElement,而不是套用 TranslateTransform,此類動畫幾乎一律會被視為受限制的動畫。 您必須啟用動畫,動畫可能會有顯著的效能問題,特別是當您嘗試支援用戶互動,而該物件正在進行動畫處理時。 因此,最好使用轉換並對其進行動畫,而不是對其他屬性進行動畫,因為那會將動畫視作依賴動畫。
若要以轉換為目標,必須有現有的 Transform 做為 renderTransform 的值。 您通常會在初始 XAML 中放置適當轉換類型的元素,有時該轉換上未設定任何屬性。
您通常會使用間接定位技術,將動畫套用至轉換屬性。 如需間接目標語法的詳細資訊,請參閱 分鏡腳本動畫 和 屬性路徑語法。
控制件的預設樣式有時會將轉換的動畫定義為其視覺狀態行為的一部分。 例如, ProgressRing 的視覺狀態會使用動畫 RotateTransform 值來「旋轉」環形中的點。
以下是如何建立轉換動畫的簡單範例。 在此情況下,它會動畫化 角度 於 旋轉變換 中,以使 矩形 繞其視覺中心旋轉。 本範例將 RotateTransform 命名為,因此不需要間接動畫目標;不過,您也可以不命名此轉換,而是命名要套用轉換效果的元素,並使用像 (UIElement.RenderTransform).(RotateTransform.Angle)這樣的間接目標。
<StackPanel Margin="15">
<StackPanel.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="myTransform"
Storyboard.TargetProperty="Angle"
From="0" To="360" Duration="0:0:5"
RepeatBehavior="Forever" />
</Storyboard>
</StackPanel.Resources>
<Rectangle Width="50" Height="50" Fill="RoyalBlue"
PointerPressed="StartAnimation">
<Rectangle.RenderTransform>
<RotateTransform x:Name="myTransform" Angle="45" CenterX="25" CenterY="25" />
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
void StartAnimation (object sender, RoutedEventArgs e) {
myStoryboard.Begin();
}
執行時考慮座標參考框架
UIElement 具有 名為 TransformToVisual的方法,此方法會產生 Transform,使兩個 UI 元素的參考座標框架相互關聯。 如果您將根視覺作為第一個參數傳遞,您可以使用此元素來與應用程式預設的坐標參考架構進行比較。 如果您已從不同的元素擷取輸入事件,或嘗試預測版面配置行為而不實際要求版面配置階段,這非常有用。
備註
(UWP) 從指標事件取得的事件資料可讓您存取 GetCurrentPoint 方法,您可以在其中指定 relativeTo 參數,以變更特定元素的座標參考框架,而不是應用程式預設值。 此方法只會在內部套用平移轉換,並在建立傳回 的 PointerPoint 物件時,為您轉換 x-y 坐標數據。
以數學方式描述轉換
轉換可以用轉換矩陣來描述。 3×3 矩陣可用來描述二維 x-y 平面中的轉換。 仿射變換矩陣可以通過相乘來組成任意數量的線性變換,例如旋轉和扭曲(切變),接著是平移。 相依轉換矩陣的最後一個數據行等於 (0, 0, 1),因此您只需要在數學描述中指定前兩個數據行的成員。
如果您有數學背景或熟悉圖形程式設計技術,也會使用矩陣來描述座標空間的轉換,轉換的數學描述可能會對您很有用。 有一個 轉換衍生類別,可讓您直接在其 3×3 矩陣中表示轉換:MatrixTransform。 MatrixTransform 具有 Matrix 屬性,其保存的結構有六個屬性:M11、M12、M21、M22、OffsetX 和 OffsetY。 每個 Matrix 屬性都會使用 Double 值,並對應至仿射變換矩陣的六個相關值(欄 1 和 2)。
| 欄 1 | 第2欄 | 欄位 3 |
|---|---|---|
| M11 | M12 | 0 |
| M21 | M22 | 0 |
| OffsetX | OffsetY | 1 |
您可以用 TranslateTransform、ScaleTransform、RotateTransform或 SkewTransform 物件所描述的任何轉換,也可以用具有 Matrix 值的 MatrixTransform 來描述。 但是,您通常只使用 TranslateTransform 和其他專案,因為這些轉換類別的屬性比在 Matrix中設定向量元件更容易概念化。 轉換的離散屬性也更容易進行動畫化;矩陣 實際上是一個結構體,而非 DependencyObject,因此無法支持對個別值進行動畫處理。
一些可讓您套用轉換作業的 XAML 設計工具會將結果串行化為 MatrixTransform。 在此情況下,最好再次使用相同的設計工具來變更轉換效果,並再次將 XAML 序列化,而不是嘗試直接在 XAML 中操縱 矩陣 值。
3D 轉換
在 Windows 10 中,XAML 引進了一個新的屬性 UIElement.Transform3D,可用來使用 UI 建立 3D 效果。 若要這樣做,請使用 PerspectiveTransform3D 將共用的 3D 透視或「相機」新增至場景,然後使用 CompositeTransform3D 來轉換 3D 空間中的元素,就像使用 CompositeTransform 一樣。 如需如何實作 3D 轉換的討論,請參閱 UIElement.Transform3D 。
對於僅適用於單一物件的較簡單 3D 效果,可以使用 UIElement.Projection 屬性。 使用 PlaneProjection 作為此屬性的值,相當於將固定透視轉換和一個或多個 3D 轉換應用于元素。 在 XAML UI
相關主題
- UIElement.Transform3D
- 適用於 XAML UI 的
3D 檢視方塊效果 - 轉換