Ketika saya tahu bahwa Flutter memberi saya kendali penuh atas semua yang ada di layar, sampai ke piksel terakhir, saya segera ingin membuat perbedaan untuk dunia UI aplikasi yang kebanyakan statis dan terprediksi. Widget full kustom yang bisa saya gambar menggunakan CustomPaint meminta agar dikeluarkan dari ScrollView atau Container khususnya. Saya ingin bebas bergerak, melakukan zoom, dan menjelajahi dunia yang bisa dibuat berkat Flutter. Widget Transform adalah wahana saya untuk menjelajahi dunia ini, dan GestureDetector menyediakan kontrolnya.


GestureDetector memberikan akses mudah ke sebagian besar gestur, dan Transform menyediakan kemampuan untuk mengubah perspektif di mana widget turunan terlihat. Keduanya adalah widget sederhana dan independen yang mengikuti pola komposabilitas Flutter. Saat kami menggabungkan keduanya, setiap gestur pada widget menjadi cara untuk menjelajah.



Pengantar transformasi

Terlepas dari kekuatannya, sesungguhnya yang dilakukan widget Transform adalah mengambil matriks transformasi dan menerapkannya pada turunannya. Ini menghasilkan terjemahan, skala, rotasi, dan bahkan kemiringan turunan terhadap induknya, semua ditetapkan oleh satu objek Matrix4 sederhana.
Matriks sangat mudah digunakan ketika melakukan transformasi karena mereka bisa dikomposisikan. Menyimpan parameter terjemahan, skala, rotasi, dan kemiringan yang terpisah mungkin terlihat intuitif pada awalnya, tetapi mudah sekali terjadi ambiguitas dengan hal-hal seperti urutan.
Bayangkan saat pengguna melakukan serangkaian gestur secara berturut-turut. Jika gestur tersebut hanya serangkaian tarik, maka kita bisa dengan mudah menyimpan transformasi akhir sebagai Offset lokasi yang dihasilkan. Namun, jika pengguna menarik, lalu memutar di lokasi yang baru, dan mengulanginya beberapa kali, bagaimana kita melacak status akhirnya? Sebuah offset dan radian ganda tidaklah cukup, bahkan jika kita juga memasukkan titik fokus. Kita harus terus melacak daftar operasi yang semakin banyak dilakukan pengguna dan mengulangi semuanya hanya untuk mencapai status akhir.
Matriks transformasi bisa dikombinasikan dengan sejumlah matriks transformasi lainnya tanpa batas, dan hasilnya selalu berupa matriks tunggal lain dengan ukuran yang sama. GPU sangat cepat dalam melakukan matematika semacam ini, bahkan paralel secara besar-besaran, seperti untuk setiap piksel di layar. Ini membuatnya sangat bagus untuk menyimpan status widget seperti Transform, dan hasilnya adalah widget yang sangat mudah digunakan developer Flutter.



Mendeteksi gestur

Jika kita menghubungkan beberapa gestur pengguna untuk memperbarui matriks transformasi menggunakan GestureDetector, maka pengguna memiliki kebebasan untuk membuka layar yang kita tampilkan kepada mereka. GestureDetector menyediakan akses mudah ke gestur seperti tarik, yang bisa kita gunakan untuk terjemahan, cubit, melakukan zoom, dan bahkan rotasi dengan dua jari.


GestureDetector menyediakan banyak callback berbeda untuk berbagai gestur dan status awal, update, dan akhir. Namun, jika Anda mengimplementasikan sesuatu seperti demo yang menggabungkan beberapa gambar, callback skala adalah yang Anda butuhkan. Callback onScaleUpdate menyediakan focalPoint, baik skala horizontal maupun vertikal, dan rotasi, semuanya ada di sini. Hal ini memungkinkan Anda untuk merespons beberapa gestur sekaligus, seperti ketika pengguna memutar dan melakukan penskalaan dalam satu gestur. Lihat ScaleUpdateDetails untuk semua hal yang disediakan callback onScaleUpdate.
Hal lain yang sering diterapkan dalam transformasi fisik seperti ini adalah inersia. Setelah pengguna menyelesaikan gestur, mereka mungkin mengharapkan transformasi berlanjut untuk sementara waktu sebelum berhenti perlahan. Flutter menyediakan parameter “velocity” di callback akhir semua gestur ini, termasuk skala. Seperti yang mungkin Anda duga dengan gerakan berbasis fisika, nilai ini lebih besar jika pengguna menggerakkan jari mereka dengan cepat dan lebih kecil jika pengguna membuat gestur lambat.
Anda bisa membuat efek inersia ini dengan infrastruktur Flutter lain yang sangat menarik, animasi Tween. Dengan menggunakan velositas dan posisi pada akhir gestur, dan pengetahuan dasar fisika, Anda bisa menemukan posisi akhir dan durasi untuk diberikan kepada Tween, dan mempersilakan Tween membereskannya. Flutter bahkan menyertakan class friction simulation untuk menangani beberapa perhitungan ini dan membuat semuanya terasa sangat realistis.



Kesimpulan

Menggabungkan Transform dan GestureDetector memberi kita fitur yang sangat kuat. Banyak hal yang bisa dilakukan, dari mulai menggerakkan papan permainan, seperti yang ditunjukkan pada screenshot, membuka peta, hingga menyediakan penampil gambar interaktif, dan lainnya.
Aplikasi yang ditampilkan di sini sekarang tersedia sebagai demo di aplikasi Flutter Gallery. Semua kode adalah bagian dari repositori open source flutter utama, dan bisa ditemukan di sumber demo transformasi. Sebagian besar logika transformasi terdapat dalam class GestureTransformable, termasuk animasi inersia.