Bagikan melalui


Gambaran umum transformasi

Pelajari cara menggunakan transformasi di Windows Runtime API, dengan mengubah sistem koordinat relatif elemen di UI. Ini dapat digunakan untuk menyesuaikan tampilan elemen XAML individual, seperti penskalaan, memutar, atau mengubah posisi di ruang x-y.

Apa itu transformasi?

Transformasi menentukan cara memetakan, atau mengubah, menunjuk dari satu ruang koordinat ke ruang koordinat lainnya. Ketika transformasi diterapkan ke elemen UI, transformasi mengubah cara elemen UI dirender ke layar sebagai bagian dari UI.

Pikirkan transformasi dalam empat klasifikasi luas: terjemahan, rotasi, penskalaan dan condong (atau geser). Untuk keperluan menggunakan API grafis untuk mengubah tampilan elemen UI, biasanya paling mudah untuk membuat transformasi yang hanya menentukan satu operasi pada satu waktu. Jadi Windows Runtime mendefinisikan kelas diskrit untuk setiap klasifikasi transformasi ini:

Dari jumlah tersebut, Anda kemungkinan besar akan menggunakan TranslateTransform dan ScaleTransform paling sering untuk skenario UI.

Anda dapat menggabungkan transformasi, dan ada dua kelas Windows Runtime yang mendukung ini: CompositeTransform dan TransformGroup. Dalam CompositeTransform, transformasi diterapkan dalam urutan ini: skala, condong, putar, terjemahkan. Gunakan TransformGroup alih-alih CompositeTransform jika Anda ingin transformasi diterapkan dalam urutan yang berbeda. Untuk informasi selengkapnya, lihat CompositeTransform.

Transformasi dan tata letak

Dalam tata letak XAML, transformasi diterapkan setelah kode tata letak selesai, sehingga perhitungan ruang yang tersedia dan keputusan tata letak lainnya telah dibuat sebelum transformasi diterapkan. Karena tata letak menjadi yang pertama, Anda terkadang akan mendapatkan hasil yang tidak terduga jika Anda mengubah elemen yang ada di sel Grid atau kontainer tata letak serupa yang mengalokasikan ruang selama tata letak. Elemen yang diubah mungkin tampak terpotong atau dikaburkan karena mencoba menggambar ke area yang tidak menghitung dimensi pasca-transformasi saat membaayakan ruang dalam kontainer induknya. Anda mungkin perlu bereksperimen dengan hasil transformasi dan menyesuaikan beberapa pengaturan. Misalnya, alih-alih mengandalkan tata letak adaptif dan ukuran bintang, Anda mungkin perlu mengubah properti Tengah atau mendeklarasikan pengukuran piksel tetap untuk ruang tata letak untuk memastikan ruang induk mengalokasikan cukup ruang.

Catatan migrasi: Windows Presentation Foundation (WPF) memiliki properti LayoutTransform yang diterapkan berubah sebelum kode tata letak. Tetapi Windows Runtime XAML tidak mendukung properti LayoutTransform . (Microsoft Silverlight juga tidak memiliki properti ini.)

Sebagai alternatif, Windows Community Toolkit menyediakan LayoutTransformControl yang menerapkan transformasi Matrix pada FrameworkElement aplikasi Anda.

Menerapkan transformasi ke elemen UI

Saat Anda menerapkan transformasi ke objek, Anda biasanya melakukannya untuk mengatur properti UIElement.RenderTransform. Menyetel properti ini tidak mengubah piksel objek secara harfiah menurut piksel. Apa yang sebenarnya dilakukan properti adalah menerapkan transformasi dalam ruang koordinat lokal tempat objek tersebut ada. Kemudian logika penyajian dan operasi (pasca-tata letak) merender ruang koordinat gabungan, membuatnya terlihat seperti objek telah mengubah tampilan dan juga berpotensi posisi tata letaknya (jika TranslateTransform diterapkan).

Secara default, setiap transformasi render berpusat pada asal sistem koordinat lokal objek target—(0,0). Satu-satunya pengecualian adalah TranslateTransform, yang tidak memiliki properti pusat untuk diatur karena efek terjemahan sama terlepas dari tempatnya berpusat. Tetapi transformasi lainnya masing-masing memiliki properti yang mengatur nilai CenterX dan CenterY .

Setiap kali Anda menggunakan transformasi dengan UIElement.RenderTransform, ingatlah bahwa ada properti lain di UIElement yang memengaruhi bagaimana transformasi berperilaku: RenderTransformOrigin. Apa yang dinyatakan RenderTransformOrigin adalah apakah seluruh transformasi harus berlaku untuk titik default (0,0) elemen atau ke beberapa titik asal lain dalam ruang koordinat relatif elemen tersebut. Untuk elemen umum, (0,0) menempatkan transformasi ke sudut kiri atas. Bergantung pada efek apa yang Anda inginkan, Anda dapat memilih untuk mengubah RenderTransformOrigin daripada menyesuaikan nilai CenterX dan CenterY pada transformasi. Perhatikan bahwa jika Anda menerapkan nilai RenderTransformOrigin dan CenterX / CenterY , hasilnya bisa sangat membingungkan, terutama jika Anda menjiwai salah satu nilai.

Untuk tujuan pengujian hit, objek tempat transformasi diterapkan terus merespons input dengan cara yang diharapkan yang konsisten dengan tampilan visualnya di ruang x-y. Misalnya, jika Anda telah menggunakan TranslateTransform untuk memindahkan Persegi Panjang 400 piksel secara lateral di UI, Persegi Panjang tersebut merespons peristiwa PointerPressed saat pengguna menekan titik tempat Persegi Muncul secara visual. Anda tidak akan mendapatkan peristiwa palsu jika pengguna menekan area tempat Persegi sebelum diterjemahkan. Untuk pertimbangan indeks z apa pun yang memengaruhi pengujian hit, menerapkan transformasi tidak ada bedanya; indeks z yang mengatur elemen mana yang menangani peristiwa input untuk titik dalam ruang x-y masih dievaluasi menggunakan urutan anak seperti yang dinyatakan dalam kontainer. Urutan tersebut biasanya sama dengan urutan di mana Anda mendeklarasikan elemen di XAML, meskipun untuk elemen turunan dari objek Canvas Anda dapat menyesuaikan urutan dengan menerapkan properti terlampir Canvas.ZIndex ke elemen turunan.

Properti transformasi lainnya

Menganimasikan transformasi

Objek transformasi dapat dianimasikan. Untuk menganimasikan Transformasi, terapkan animasi jenis yang kompatibel ke properti yang ingin Anda animasikan. Ini biasanya berarti Anda menggunakan objek DoubleAnimation atau DoubleAnimationUsingKeyFrames untuk menentukan animasi, karena semua properti transformasi berjenis Double. Animasi yang memengaruhi transformasi yang digunakan untuk nilai UIElement.RenderTransform tidak dianggap sebagai animasi dependen, bahkan jika mereka memiliki durasi bukan nol. Untuk informasi selengkapnya tentang animasi dependen, lihat Animasi storyboarded.

Jika Anda menganimasikan properti untuk menghasilkan efek yang mirip dengan transformasi dalam hal tampilan visual bersih—misalnya, menjiwai Lebar dan Tinggi FrameworkElement daripada menerapkan TranslateTransform—animasi tersebut hampir selalu diperlakukan sebagai animasi dependen. Anda harus mengaktifkan animasi dan mungkin ada masalah performa yang signifikan dengan animasi, terutama jika Anda mencoba mendukung interaksi pengguna saat objek tersebut sedang dianimasikan. Untuk alasan itu, lebih baik menggunakan transformasi dan menganimasikannya daripada menganimasikan properti lain di mana animasi akan diperlakukan sebagai animasi dependen.

Untuk menargetkan transformasi, harus ada Transformasi yang ada sebagai nilai untuk RenderTransform. Anda biasanya menempatkan elemen untuk jenis transformasi yang sesuai di XAML awal, kadang-kadang tanpa properti yang diatur pada transformasi tersebut.

Anda biasanya menggunakan teknik penargetan tidak langsung untuk menerapkan animasi ke properti transformasi. Untuk informasi selengkapnya tentang sintaks penargetan tidak langsung, lihat Animasi storyboarded dan Sintaks jalur properti.

Gaya default untuk kontrol terkadang menentukan animasi transformasi sebagai bagian dari perilaku status visualnya. Misalnya, status visual untuk ProgressRing menggunakan nilai RotateTransform animasi untuk "memutar" titik di cincin.

Berikut adalah contoh sederhana tentang cara menganimasikan transformasi. Dalam hal ini, ini menanimasikan Sudut RotateTransform untuk memutar Persegi panjang di tempat di sekitar pusat visualnya. Contoh ini menamai RotateTransform sehingga tidak memerlukan penargetan animasi tidak langsung, tetapi Anda dapat membiarkan transformasi tanpa nama, memberi nama elemen tempat transformasi diterapkan, dan menggunakan penargetan tidak langsung seperti (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();
}

Akuntansi untuk bingkai koordinat referensi pada waktu proses

UIElement memiliki metode bernama TransformToVisual, yang dapat menghasilkan Transformasi yang menghubungkan bingkai koordinat referensi untuk dua elemen UI. Anda dapat menggunakan ini untuk membandingkan elemen dengan bingkai referensi koordinat default aplikasi jika Anda meneruskan visual akar sebagai parameter pertama. Ini dapat berguna jika Anda telah mengambil peristiwa input dari elemen yang berbeda, atau jika Anda mencoba memprediksi perilaku tata letak tanpa benar-benar meminta kode tata letak.

Data peristiwa yang diperoleh dari peristiwa pointer menyediakan akses ke metode GetCurrentPoint , di mana Anda dapat menentukan parameter relativeTo untuk mengubah bingkai koordinat referensi ke elemen tertentu daripada default aplikasi. Pendekatan ini hanya menerapkan transformasi terjemahan secara internal dan mengubah data koordinat x-y untuk Anda saat membuat objek PointerPoint yang dikembalikan.

Menjelaskan transformasi secara matematis

Transformasi dapat dijelaskan dalam hal matriks transformasi. Matriks 3×3 digunakan untuk menggambarkan transformasi dalam bidang x-y dua dimensi. Matriks transformasi affine dapat dikalikan untuk membentuk sejumlah transformasi linier, seperti rotasi dan condong (geser), diikuti dengan terjemahan. Kolom akhir matriks transformasi afin sama dengan (0, 0, 1), jadi Anda hanya perlu menentukan anggota dari dua kolom pertama dalam deskripsi matematika.

Deskripsi matematika dari transformasi mungkin berguna bagi Anda jika Anda memiliki latar belakang matematika atau keakraban dengan teknik pemrograman grafis yang juga menggunakan matriks untuk menggambarkan transformasi ruang koordinat. Ada kelas turunan Transformasi yang memungkinkan Anda mengekspresikan transformasi secara langsung dalam hal matriks 3×3: MatrixTransform. MatrixTransform memiliki properti Matriks, yang menyimpan struktur yang memiliki enam properti: M11, M12, M21, M22, OffsetX dan OffsetY. Setiap properti Matriks menggunakan nilai Ganda dan sesuai dengan enam nilai yang relevan (kolom 1 dan 2) dari matriks transformasi afin.

Kolom 1 Kolom 2 Kolom 3
M11 M12 0
M21 M22 0
OffsetX Offsety 1

Setiap transformasi yang dapat Anda jelaskan dengan objek TranslateTransform, ScaleTransform, RotateTransform, atau SkewTransform dapat dijelaskan secara merata oleh MatrixTransform dengan nilai Matriks. Tetapi Anda biasanya hanya menggunakan TranslateTransform dan yang lain karena properti pada kelas transformasi tersebut lebih mudah dikonsep daripada mengatur komponen vektor dalam Matriks. Juga lebih mudah untuk menganimasikan sifat transformasi diskrit; Matriks sebenarnya adalah struktur dan bukan DependencyObject, sehingga tidak dapat mendukung nilai individual animasi.

Beberapa alat desain XAML yang memungkinkan Anda menerapkan operasi transformasi akan menserialisasikan hasilnya sebagai MatrixTransform. Dalam hal ini, mungkin yang terbaik adalah menggunakan alat desain yang sama lagi untuk mengubah efek transformasi dan menserialisasikan XAML lagi, daripada mencoba memanipulasi nilai Matriks sendiri langsung di XAML.

Transformasi 3-D

Di Windows 10, XAML memperkenalkan properti baru, UIElement.Transform3D, yang dapat digunakan untuk membuat efek 3D dengan UI. Untuk melakukan ini, gunakan PerspectiveTransform3D untuk menambahkan perspektif 3D bersama atau "kamera" ke adegan Anda, lalu gunakan CompositeTransform3D untuk mengubah elemen di ruang 3D, seperti Anda akan menggunakan CompositeTransform. Lihat UIElement.Transform3D untuk diskusi tentang cara menerapkan transformasi 3D.

Untuk efek 3D yang lebih sederhana yang hanya berlaku untuk satu objek, properti UIElement.Projection dapat digunakan. Menggunakan PlaneProjection sebagai nilai untuk properti ini setara dengan menerapkan transformasi perspektif tetap dan satu atau beberapa transformasi 3D ke elemen . Jenis transformasi ini dijelaskan secara lebih rinci dalam efek perspektif 3-D untuk UI XAML.