Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. React Native
Code

Contoh Animasi Praktis dalam React Native

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by AaliyaA (you can also view the original English article)

Dalam tutorial ini, Anda akan belajar bagaimana menerapkan animasi yang sering digunakan dalam aplikasi mobile. Secara khusus, Anda akan belajar bagaimana menerapkan animasi yang:

  • Provide visual feedback: misalnya, ketika pengguna menekan tombol, Anda ingin menggunakan animasi untuk menunjukkan kepada pengguna bahwa tombol tersebut benar-benar ditekan.
  • Show the current system status: ketika melakukan proses yang tidak selesai secara instan (misalnya ketika mengunggah foto atau mengirim email), Anda ingin menampilkan animasi sehingga pengguna memiliki gagasan berapa lama proses akan berlangsung.
  • Visually connect transition states: ketika pengguna menekan tombol untuk membawa sesuatu ke depan layar, transisi ini harus dianimasikan agar pengguna tahu dari mana asal elemen tersebut.
  • Grab the user's attention: ketika ada pemberitahuan penting, Anda dapat menggunakan animasi untuk menarik perhatian pengguna.

Tutorial ini adalah sekuel untuk Animate Your React Native App post. Jadi jika Anda baru dalam animasi di React Native, pastikan untuk memeriksanya terlebih dahulu, karena beberapa konsep yang akan digunakan dalam tutorial ini dijelaskan secara lebih terperinci di sana.

Juga, jika Anda ingin mengikuti, Anda dapat menemukan kode sumber lengkap yang digunakan dalam tutorial ini di GitHub repo.

Apa yang sedang kita bangun

Kita akan membangun aplikasi yang mengimplementasikan setiap jenis animasi yang saya sebutkan sebelumnya. Secara khusus, kita akan membuat halaman-halaman berikut, yang masing-masing akan mengimplementasikan animasi untuk tujuan yang berbeda.

  • News Page: menggunakan isyarat untuk memberikan umpan balik visual dan menunjukkan status sistem saat ini.
  • Buttons Page: menggunakan tombol untuk memberikan umpan balik visual dan menunjukkan status sistem saat ini.
  • Progress Page: menggunakan bilah progres untuk menunjukkan status sistem saat ini.
  • Expand Page: secara visual menghubungkan status transisi menggunakan gerakan memperluas dan menyusut.
  • AttentionSeeker Page: menggunakan gerakan eye-catching untuk menarik perhatian pengguna.

Jika Anda ingin melihat preview dari masing-masing animasi, periksa Imgur album ini.

Mendirikan Proyek

Mulai dengan membuat proyek Native React baru:

Setelah proyek dibuat, navigasi di dalam folder yang baru dibuat, buka file package.json, dan tambahkan yang berikut ke dependencies:

Jalankan npm install untuk menginstal kedua paket tersebut. react-native-animatable digunakan untuk mengimplementasikan animasi dengan mudah, dan react-native-vector-icons digunakan untuk membuat ikon untuk halaman ekspansi nanti. Jika Anda tidak ingin menggunakan ikon, Anda bisa tetap menggunakan komponen Text. Jika tidak, ikuti petunjuk pemasangan of react-native-vector-icons pada their GitHub page.

Membangun Aplikasi

Buka file index.android.js atau file index.ios.js dan ganti konten yang ada dengan yang berikut:

Setelah selesai, pastikan untuk membuat file yang sesuai sehingga Anda tidak mendapatkan kesalahan apa pun. Semua file yang akan kita kerjakan disimpan di bawah direktori src. Di dalam direktori tersebut adalah folder berikut:

  • components: komponen reusable yang akan digunakan oleh komponen atau halaman lain.
  • img: gambar yang akan digunakan di seluruh aplikasi. Anda bisa mendapatkan gambar dari GitHub repo.
  • pages: halaman-halaman aplikasi.

Halaman Berita

Mari kita mulai dengan Halaman berita.

Pertama, tambahkan komponen yang akan kita gunakan:

Anda seharusnya sudah terbiasa dengan sebagian besar dari ini, kecuali untuk RefreshControl dan komponen NewsItem kustom, yang akan kita buat nanti. RefreshControl digunakan untuk menambahkan fungsionalitas "pull to refresh" dalam komponen ScrollView atau ListView. Jadi sebenarnya yang akan menangani gerakan menggesek ke bawah dan animasi untuk kita. Tidak perlu menerapkan milik kita sendiri. Ketika Anda mendapatkan lebih banyak pengalaman dalam menggunakan React Native, Anda akan melihat bahwa animasi sebenarnya dibangun untuk beberapa components, dan tidak perlu menggunakan kelas Animated untuk mengimplementasikan sendiri.

Buat komponen yang akan menampung seluruh halaman:

Di dalam constructor, menginisialisasi nilai animasi untuk menyimpan opasitas saat ini (opacityValue) dari item berita. Kita ingin agar berita tidak terlalu buram saat item berita sedang disegarkan. Ini memberi pengguna sebuah ide bahwa mereka tidak dapat berinteraksi dengan seluruh halaman sementara item berita sedang disegarkan. is_news_refreshing digunakan sebagai saklar untuk menunjukkan apakah item berita sedang disegarkan atau tidak.

Fungsi opacity () adalah salah satu yang akan memicu animasi untuk mengubah opacity.

Di dalam fungsi render (), tentukan bagaimana nilai opasitas akan berubah. Di sini, outputRange adalah [1, 0, 1], yang berarti bahwa itu akan mulai pada opasitas penuh, kemudian pergi ke nol opacity, dan kemudian kembali ke opacity penuh lagi. Sebagaimana didefinisikan di dalam opacity () fungsi, transisi ini akan dilakukan selama 3,500 milidetik (3,5 detik).

Komponen <RefreshControl>  ditambahkan ke <ScrollView>. Ini memanggil fungsi refreshNews () kapan saja pengguna menggesek ke bawah saat mereka berada di bagian atas daftar (ketika scrollY adalah 0). Anda dapat menambahkan colors prop untuk menyesuaikan warna animasi refresh.

Di dalam <ScrollView>, gunakan komponen<Animated.View> dan atur style ke nilai opacity:

Fungsi refreshNews() memanggil fungsi opacity() dan memperbaharui nilai is_news_refreshing untuk true. Hal ini memungkinkan komponen <RefreshControl>mengetahui bahwa animasi refresh seharusnya sudah ditampilkan. Setelah itu, menggunakan setTimeout () untuk memperbarui nilai is_news_refreshing kembali ke false setelah 3.500 milidetik (3,5 detik). Ini akan menyembunyikan refresh animasi dari tampilan. Pada saat itu, animasi opacity juga harus dilakukan karena kita menetapkan nilai yang sama untuk durasi dalam fungsi opacity sebelumnya.

renderNewsItems () mengambil larik item berita yang kami nyatakan sebelumnya di dalam constructor() dan menuliskan masing-masing menggunakan <NewsItem> komponen.

NewsItem Component

Komponen NewsItem (src/components/NewsItem.js) menjadikan judul dan situs berita dan membungkus mereka di dalam <Button>komponen sehingga mereka dapat berinteraksi dengannya.

Button Component

The Button component (src/components/Button.js) menggunakan komponen TouchableHighlight untuk membuat sebuah button. Alat peraga underlayColor digunakan untuk menentukan warna lapisan bawah ketika tombol ditekan. Ini adalah cara React Native's built-in menyediakan umpan balik visual; kemudian di bagian Buttons Page, kita akan melihat cara lain button dapat memberikan umpan balik visual.

Kembali ke komponen NewsPage, tambahkan styling:

Buttons Page

Button page (src / pages / ButtonsPage.js) menunjukkan tiga jenis button: button yang biasa digunakan yang disorot,button yang menjadi sedikit lebih besar, dan button yang menunjukkan status operasi saat ini. Memulai dengan menambahkan komponen yang diperlukan:

Sebelumnya, Anda melihat bagaimana the Button component bekerja, jadi kita hanya akan fokus pada dua button lain.

Scaling Button Component

Pertama, mari kita lihat pada button skala (src/components/ScalingButton.js). Tidak seperti buttonl yang kita gunakan sebelumnya, ini menggunakan komponen TouchableWithoutFeedback built-in untuk membuat button. Sebelumnya, kami menggunakan komponen TouchableHighlight, yang dilengkapi dengan semua lonceng dan peluit untuk sesuatu yang dianggap sebagai button. Anda dapat memikirkan TouchableWithoutFeedback sebagai button bare-bones di mana Anda harus menentukan semua yang perlu dilakukan ketika pengguna mengetuknya. Ini sangat cocok untuk kasus penggunaan kita karena kita tidak perlu khawatir tentang perilaku button default yang menghalangi animasi yang ingin kita terapkan.

Sama seperti komponen Button, ini akan menjadi komponen fungsional karena kita tidak benar-benar perlu bekerja dengan negara.

Di dalam komponen, buat nilai animasi yang akan menyimpan skala button saat ini.

Tambahkan fungsi yang akan memulai animasi skala . Kita tidak ingin aplikasi tampak lambat, jadi buat duration serendah mungkin tetapi juga cukup tinggi sehingga pengguna dapat melihat apa yang terjadi. 300 milidetik adalah titik awal yang baik, tetapi merasa bebas untuk bermain-main dengan nilai.

Tentukan bagaimana button akan diskalakan (outputRange) tergantung pada nilai saat ini (inputRange). Kita tidak ingin itu menjadi terlalu besar sehingga kita tetap dengan 1,1 sebagai nilai tertinggi. Ini berarti akan lebih besar 0,1 dari ukuran aslinya di tengah (0,5) seluruh animasi.

Fungsi onPress () menjalankan animasi skala terlebih dahulu sebelum memanggil metode yang diteruskan oleh pengguna melalui alat peraga.

Fungsi getContent () menampilkan komponen anak jika tersedia. Jika tidak, komponen Text yang berisi label props ditampilkan.

Tambahkan gaya dan ekspor button:

Stateful Button Component

Berikutnya adalah stateful button  (src/components/StatefulButton.js). Saat ditekan, button ini akan mengubah warna latar belakangnya dan menampilkan gambar pemuatan hingga operasi selesai.

Memuat gambar yang kita akan menggunakan adalah animasi gif. Secara default, React Native on Android tidak mendukung gif animasi. Untuk membuatnya bekerja, Anda harus mengedit android/app/build.gradle file dan menambahkan compile 'com.facebook.fresco:animated-gif:0.12.0'  di bawah dependencies seperti:

Jika Anda menggunakan iOS, gif animasi harus bekerja secara default.

Kembali ke komponen button stateful, seperti button scaling, ini menggunakan komponen TouchableWithoutFeedback untuk membuat button  karena itu juga akan mengimplementasikan animasinya sendiri.

Tidak seperti button skala, komponen ini akan menjadi komponen berbasis kelas penuh karena mengelola negara sendiri.

Di dalam constructor(), buat nilai animasi untuk menyimpan warna latar belakang saat ini. Setelah itu, inisialisasi status yang berfungsi sebagai saklar untuk menyimpan status tombol saat ini. Secara default, ini disetel ke false. Setelah pengguna mengetuk button, itu akan diperbarui menjadi true dan hanya akan disetel ke false lagi setelah proses imajiner selesai dijalankan.

Di dalam fungsi render (), tentukan warna latar belakang berbeda yang akan digunakan berdasarkan nilai saat ini dari nilai animasi.

Selanjutnya, membungkus semuanya dalam komponen TouchableWithoutFeedback, dan dalam <Animated.View>adalah tempat warna latar belakang animasi diterapkan. Kita juga merender citra pemuat jika nilai is_loading saat ini true. Label button juga berubah berdasarkan nilai ini.

Ketika button ditekan, pertama-tama menjalankan fungsi yang dilewatkan melalui props sebelum melakukan animasi.

Fungsi changeColor() bertanggung jawab untuk memperbarui negara dan menghidupkan warna latar belakang button. Di sini kita akan mengasumsikan bahwa proses akan mengambil 3.000 milidetik (3 detik). Tapi dalam skenario dunia nyata, Anda tidak dapat selalu tahu berapa lama proses yang akan berlangsung. Yang dapat Anda lakukan adalah menjalankan animasi untuk jangka waktu yang lebih pendek dan kemudian memanggil fungsi changeColor () secara rekursif hingga proses selesai.

Tambahkan Gaya:

Kembali pada halaman Buttons : buat komponen, render ketiga jenis button , dan tambahkan gaya mereka.

Progress Page

Laman Kemajuan (src / pages / ProgressPage.js) menampilkan animasi kemajuan kepada pengguna selama proses yang berjalan lama. Kami akan mengimplementasikan sendiri alih-alih menggunakan komponen bawaan karena React Native tidak memiliki cara terpadu untuk menerapkan animasi bilah kemajuan. Jika Anda tertarik, berikut adalah tautan ke dua komponen bilah progres yang ada di dalamnya:

Untuk membangun halaman Kemajuan kita, mulailah dengan mengimpor komponen yang kita butuhkan:

Kita menggunakan Dimensiuntuk mendapatkan lebar perangkat. Dari situ, kita bisa menghitung lebar yang tersedia untuk progress bar. Kita akan melakukannya dengan mengurangi jumlah paddings kiri dan kanan yang akan kita tambahkan ke kontainer, dan juga batas kiri dan kanan yang akan kita tambahkan ke bilah progres bar.

Untuk rumus di atas agar masuk akal, mari lewati langsung ke gaya:

The container memiliki padding 20 di setiap sisi — sehingga kita kurangi 40 dari the available_width. The progress_container memiliki batas 6 di setiap sisi, jadi kami hanya menggandakan itu lagi dan mengurangi 12 dari lebar bilah kemajuan.

Membuat komponen, dan di dalam konstruktor buat nilai animasi untuk menyimpan nilai animasi saat ini untuk bilah kemajuan.

Saya mengatakan "values" karena kali ini kita akan menggunakan nilai animasi tunggal ini untuk menganimasi lebar dan warna background  kemajuan. Anda akan melihat ini dalam tindakan nanti.

Selain itu, Anda juga perlu menginisialisasi kemajuan saat ini di negara bagian.

Di dalam fungsi render (), progress_container bertindak sebagai wadah untuk bilah progres, dan  <Animated.View> di dalamnya adalah bilah progres aktual yang lebar dan warna latar belakangnya akan berubah tergantung pada kemajuan saat ini. Di bawah ini, kami juga memberikan kemajuan saat ini dalam bentuk teks (0% untuk 100%).

Gaya untuk progress bar dikembalikan oleh fungsi getProgressStyles (). Di sini kita sedang menggunakan nilai animasi dari sebelumnya untuk menghitung lebar dan latar belakang warna. Hal ini dilakukan agar tidak perlu membuat nilai animasi yang terpisah untuk setiap animasi karena kita sedang interpolasi nilai yang sama pula. Jika kita menggunakan dua nilai-nilai terpisah, kita akan perlu memiliki dua animasi secara paralel, yang kurang efisien.

Animasi segera dijalankan setelah komponen dipasang. Mulailah dengan menetapkan nilai awal kemajuan, dan kemudian menambahkan pendengar untuk nilai kemajuan saat ini. Hal ini memungkinkan kita untuk memperbarui negara setiap kali perubahan nilai kemajuan. Kita menggunakan parseInt (), jadi nilai progresnya dikonversi ke bilangan bulat. Setelah itu, kita mulai animasi dengan durasi 7.000 milidetik (7 detik). Setelah itu selesai, kita mengubah teks progress untuk selesai!

Memperluas Halaman

Laman perluasan (src / pages / ExpandPage.js) menunjukkan cara menghubungkan status transisi secara visual menggunakan gerakan yang meluas dan menyusut. Penting untuk menunjukkan kepada pengguna bagaimana elemen tertentu muncul. Ini menjawab pertanyaan dari mana elemen itu berasal dan apa perannya dalam konteks saat ini. Seperti biasa, mulai dengan mengimpor hal-hal yang kita butuhkan:

Di dalam constructor(), buat nilai animasi yang akan menyimpan posisi-y saat ini dari menu. Idenya adalah memiliki kotak besar yang cukup untuk memuat semua item menu.

Awalnya, kotak itu akan memiliki nilai negatif untuk bottom bawah. Ini berarti bahwa hanya ujung seluruh kotak akan ditampilkan secara default. Setelah pengguna mengetuk menu, seluruh kotak akan terlihat seolah-olah diperluas, padahal kenyataannya kita hanya mengubah bottom bawah sehingga semuanya ditampilkan.

Anda mungkin bertanya-tanya mengapa kita menggunakan pendekatan ini daripada hanya menskalakan kotak untuk mengakomodasi semua anak-anaknya. Itu karena kita hanya perlu menskala atribut ketinggian. Pikirkan apa yang terjadi pada gambar ketika Anda hanya menyesuaikan tinggi atau lebar mereka saja — mereka terlihat memanjang. Hal yang sama akan terjadi pada elemen-elemen di dalam kotak.

Kembali ke constructor(), kita juga menambahkan bendera negara yang menunjukkan apakah menu saat ini diperluas atau tidak. Kita memerlukan ini karena kita perlu menyembunyikan tombol untuk memperluas menu jika menu sudah diperluas.

Di dalam fungsi render (), tentukan bagaimana bottom bawah akan diterjemahkan. InputRange adalah 0 dan 1, dan outputRange adalah 0 dan -300. Jadi jika y_translate memiliki nilai 0, tidak ada yang akan terjadi karena ekuivalen outputRange adalah 0. Tetapi jika nilainya menjadi 1, posisi bottom menu diterjemahkan ke -300 dari posisi semula.

Perhatikan tanda negatif, karena jika itu hanya 300, kotak akan turun lebih jauh. Jika angka negatif, sebaliknya akan terjadi.

Agar ini lebih masuk akal, mari lewati ke gaya:

Perhatikan gaya footer_menu. height totalnya ditetapkan menjadi 350, dan posisi bottom adalah -300, yang berarti hanya 50 teratas yang ditampilkan secara default. Ketika menerjemahkan animasi dijalankan untuk memperluas menu, posisi bottom berakhir dengan nilai 0. Mengapa? Karena jika Anda masih ingat aturan ketika mengurangi angka negatif, dua tanda minus menjadi positif. Jadi (-300) - (-300) menjadi (-300) + 300.

Kita semua tahu apa yang terjadi ketika menambahkan angka positif dan negatif: mereka membatalkan satu sama lain. Jadi posisi bottom akhirnya menjadi 0, dan seluruh menu akan ditampilkan.

Kembali ke fungsi render (), kita memiliki konten utama (body) dan menu footer, yang merupakan salah satu yang akan diperluas dan menyusut. The translateY transform digunakan untuk menerjemahkan posisinya di sumbu Y. Karena seluruh container memiliki flex: 10 dan body juga flex: 10, titik awal sebenarnya di bagian paling bawah layar.

Di dalam <Animated.View>adalah tip_menu dan menu lengkap. Jika menu diperluas, kami tidak ingin menu tip ditampilkan, jadi kami hanya merendernya jika menu_expanded disetel ke false.

Di sisi lain, kami hanya ingin menampilkan menu lengkap jika menu_expanded disetel ke true. Setiap button akan mengecilkan menu kembali ke posisi semula.

Saat membuka menu, status harus diperbarui terlebih dahulu sehingga menu tersembunyi akan ditampilkan. Hanya setelah selesai, animasi terjemahan akan dijalankan. Ini menggunakan Animated.spring sebagai lawan dari Animated.timing untuk menambahkan sedikit main-main ke animasi. Semakin tinggi nilai yang Anda berikan pada friction, semakin sedikit pemantulan di sana. Ingat untuk tidak berlebihan pada animasi Anda karena alih-alih membantu pengguna, mereka bisa menjadi jengkel.

hideMenu () melakukan kebalikan dari showMenu (), jadi kita cukup membalikkan apa yang dilakukannya:

Halaman AttentionSeeker

Last but not least adalah halaman attentionseeker (src / pages / AttentionSeekerPage.js). Saya tahu bahwa tutorial ini sudah cukup panjang, jadi untuk mempersingkatnya, mari gunakan paket react-native-animatable untuk mengimplementasikan animasi untuk halaman ini.

Buat larik yang berisi jenis animasi dan warna latar belakang yang akan digunakan untuk setiap kotak:

Membuat komponen:

Fungsi render () menggunakan fungsi renderBoxes () untuk membuat tiga baris yang akan membuat masing-masing tiga kotak.

Fungsi renderBoxes() menuliskan kotak animasi. Ini menggunakan indeks awal yang disediakan sebagai argumen untuk mengekstrak bagian tertentu dari array dan membuatnya secara individual.

Di sini kita menggunakan komponen<Animatable.View>bukan <Animated.View>. Ini menerima animation dan iterationCount Jumlah sebagai alat peraga. The animation menentukan jenis animasi yang ingin Anda lakukan, dan iterationCount menentukan berapa kali Anda ingin menjalankan animasi. Dalam hal ini, kita hanya ingin bug pengguna sampai mereka menekan kotak.

stopAnimation() berhenti kotak dari menjadi animasi. Ini menggunakan "ref" untuk mengidentifikasi setiap kotak secara unik sehingga mereka dapat dihentikan secara individual.

Akhirnya, tambahkan gaya:

Kesimpulan

Dalam tutorial ini, Anda telah belajar bagaimana menerapkan beberapa animasi yang biasa digunakan dalam aplikasi seluler. Secara khusus, Anda telah belajar bagaimana menerapkan animasi yang memberikan umpan balik visual, menunjukkan status sistem saat ini, secara visual menghubungkan status transisi, dan menarik perhatian pengguna.

Seperti biasa, masih banyak yang harus dipelajari saat terkait animasi. Misalnya, kita masih belum menyentuh bidang-bidang berikut:

  • Cara melakukan animasi pada gerakan pengguna tertentu seperti menyeret, menjentikkan, mencubit, dan menyebar. Misalnya, ketika pengguna menggunakan gerakan sebar, Anda harus menggunakan animasi skala untuk menunjukkan bagaimana elemen yang terlibat menjadi lebih besar.
  • Bagaimana menganimasikan transisi berbagai elemen dari satu negara ke negara lain. Misalnya, ketika menampilkan daftar foto, Anda mungkin ingin melakukan animasi terhuyung untuk menunda pemunculan semua foto.
  • Intro animasi untuk pengguna pertama kali aplikasi. Video dapat digunakan sebagai alternatif, tetapi ini juga tempat yang bagus untuk menerapkan animasi.

Mungkin saya akan membahas beberapa topik tersebut di tutorial selanjutnya. Sementara itu, lihat beberapa kursus dan tutorial kita lainnya tentang React Native!


Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.