
Animasi dalam aplikasi Bereaksi adalah topik populer dan dibahas. Faktanya adalah ada banyak cara untuk membuatnya. Beberapa pengembang menggunakan CSS dengan menambahkan tag ke kelas HTML. Cara hebat, itu layak digunakan. Tetapi, jika Anda ingin bekerja dengan jenis animasi yang kompleks, Anda harus meluangkan waktu untuk mempelajari GreenSock, itu adalah platform yang populer dan kuat. Ada juga banyak perpustakaan dan komponen untuk membuat animasi. Mari kita bicarakan mereka.
Artikel ini membahas lima cara untuk menghidupkan aplikasi Bereaksi:
- CSS
- ReactTransitionGroup;
- Bereaksi-animasi
- Bereaksi-mengungkapkan;
- Desain TweenOne dan Semut.
Skillbox merekomendasikan: Kursus pendidikan online "Pengembang Java Profesi" .
Kami mengingatkan Anda: untuk semua pembaca "Habr" - diskon 10.000 rubel saat mendaftar untuk kursus Skillbox apa pun menggunakan kode promo "Habr".
Semua contoh tersedia di
repositori (dari sini sumber dimasukkan ke dalam artikel, bukan gambar, seperti dalam artikel asli).
CSS
Metode ini disebutkan di awal, dan itu sangat bagus. Jika alih-alih mengimpor pustaka JavaScript dan menggunakannya, rakitan akan kecil, browser tidak akan membutuhkan banyak sumber daya. Dan ini, tentu saja, mempengaruhi kinerja aplikasi. Jika animasi Anda seharusnya relatif sederhana, perhatikan metode ini.
Contohnya adalah menu animasi:

Ini relatif sederhana, dengan properti CSS dan pemicu seperti className = "is-nav-open" untuk tag HTML.
Ada beberapa cara untuk menggunakan metode ini. Misalnya, buat pembungkus di atas navigasi, lalu aktifkan perubahan bidang. Karena navigasi memiliki lebar konstan 250px, lebar pembungkus dengan properti margin-kiri atau translateX harus sama lebar. Jika Anda perlu menunjukkan navigasi, tambahkan className = "is-nav-open" untuk wrapper dan pindahkan wrapper ke margin-left / translateX: 0;.
Pada akhirnya, sumber animasi akan terlihat seperti ini:
export default class ExampleCss extends Component { handleClick() { const wrapper = document.getElementById('wrapper'); wrapper.classList.toggle('is-nav-open') } render() { return ( <div id="wrapper" className="wrapper"> <div className="nav"> <icon className="nav__icon" type="menu-fold" onClick={() => this.handleClick()}/> <div className="nav__body"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Beatae ducimus est laudantium libero nam optio repellat sit unde voluptatum? </div> </div> </div> ); } }
Dan ini adalah gaya CSS:
.wrapper { display: flex; width: 100%; height: 100%; transition: margin .5s; margin: 0 0 0 -250px; } .wrapper.is-nav-open { margin-left: 0; } .nav { position: relative; width: 250px; height: 20px; padding: 20px; border-right: 1px solid #ccc; } .nav__icon { position: absolute; top: 0; right: -60px; padding: 20px; font-size: 20px; cursor: pointer; transition: color .3s; } .nav__icon:hover { color: #5eb2ff; }
Saya ulangi, jika animasinya relatif sederhana, maka metode ini adalah yang utama. Pengguna akan menghargai kinerja browser.
ReactTransitionGroup
Komponen ReactTransitionGroup dikembangkan oleh tim komunitas ReactJS. Dengannya, Anda dapat dengan mudah mengimplementasikan animasi dan transisi CSS dasar.
ReactTransitionGroup dirancang untuk mengubah kelas ketika mengubah siklus hidup komponen. Ini memiliki ukuran kecil, perlu diinstal dalam paket untuk aplikasi Bereaksi, yang akan sedikit meningkatkan ukuran perakitan keseluruhan. Selain itu, Anda dapat menggunakan CDN.
ReactTransitionGroup memiliki tiga elemen, yaitu Transition, CSSTransition, dan TransitionGroup. Untuk memulai animasi, Anda harus membungkus komponen di dalamnya. Style, pada gilirannya, perlu ditulis dalam kelas CSS.
Inilah animasi, dan kemudian cara mengimplementasikannya.

Langkah pertama adalah mengimpor CSSTransitionGroup dari grup reaksi-transisi. Setelah itu, Anda perlu membungkus daftar dan mengatur properti transitionName. Setiap kali Anda menambah atau menghapus anak di CSSTransitionGroup, itu mendapatkan gaya animasi.
<CSSTransitionGroup transitionName="example"> {items} </CSSTransitionGroup>
Saat mengatur properti transitionName = "example", kelas dalam style sheet harus dimulai dengan nama contoh.
.example-enter { opacity: 0.01; } .example-enter.example-enter-active { opacity: 1; transition: opacity 300ms ease-in; } .example-leave { opacity: 1; } .example-leave.example-leave-active { opacity: 0.01; transition: opacity 300ms ease-in;
Di atas adalah contoh menggunakan ReactTransitionGroup.
Anda juga memerlukan logika, dan dua metode untuk menerapkan contoh menambahkan daftar kontak.
Metode handleAdd pertama - menambahkan kontak baru, mendapatkan nama acak, yang kemudian dimasukkan ke dalam array state.items.
Untuk menghapus kontak dengan indeks di array state.items, gunakan handleRemove.
import React, { Component, Fragment } from 'react'; import { CSSTransitionGroup } from 'react-transition-group' import random from 'random-name' import Button from './button' import Item from './item' import './style.css'; export default class ReactTransitionGroup extends Component { constructor(props) { super(props); this.state = { items: ['Natividad Steen']}; this.handleAdd = this.handleAdd.bind(this); } handleAdd() { let newItems = this.state.items; newItems.push(random()); this.setState({ items: newItems }); } render () { const items = this.state.items.map((item, i) => ( <Item item={item} key={i} keyDelete={i} handleRemove={(i) => this.handleRemove(i)} /> )); return ( <Fragment> <Button onClick={this.handleAdd}/> <div className="project"> <CSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300} > {items} </CSSTransitionGroup> </div> </Fragment> ); } };
Bereaksi animasi
React-animations adalah perpustakaan yang dibangun di atas animate.css. Mudah digunakan, ia memiliki banyak koleksi animasi yang berbeda. Pustaka ini kompatibel dengan pustaka gaya inline apa pun yang mendukung penggunaan objek untuk menentukan bingkai utama animasi, termasuk Radium, Aphrodite, atau komponen yang ditata.

Saya tahu apa yang Anda pikirkan:

Sekarang mari kita lihat bagaimana ini bekerja dengan contoh animasi bouncing.

Pertama, impor animasi dari animasi reaksi.
const Bounce = styled.div`animation: 2s $ {keyframes` $ {bounce} `} infinite`;Kemudian, setelah membuat komponen, kami membungkus kode HTML atau komponen untuk animasi.
<bounce><h1>Hello Animation Bounce</h1></bounce>
Contoh:
import React, { Component } from 'react'; import styled, { keyframes } from 'styled-components'; import { bounce } from 'react-animations'; import './style.css'; const Bounce = styled.div`animation: 2s ${keyframes`${bounce}`} infinite`; export default class ReactAnimations extends Component { render() { return ( <Bounce><h1>Hello Animation Bounce</h1></bounce> ); } }
Semuanya berfungsi, animasinya sangat sederhana. Selain itu, ada solusi hebat untuk menggunakan animasi bouncing saat menggulir -
react-animate-on-scroll .
Bereaksi-mengungkapkan
Kerangka kerja React Reveal memiliki animasi dasar, termasuk fading, refleksi, penskalaan, rotasi, dan banyak lagi. Itu memungkinkan untuk bekerja dengan semua animasi menggunakan alat peraga. Jadi, Anda dapat menentukan pengaturan tambahan, termasuk posisi, penundaan, jarak, kaskade, dan lainnya. Efek CSS lainnya dapat digunakan, termasuk rendering sisi server dan komponen tingkat tinggi. Secara umum, jika Anda memerlukan animasi gulir, Anda harus menggunakan kerangka kerja ini.
import Fade from 'react-reveal/Fade'; <Fade top> <h1>Title</h1> </Fade>

Ada lima blok secara total, masing-masing memiliki halaman layar penuh dan judul.
import React, { Component, Fragment } from 'react'; import Fade from 'react-reveal/Fade'; const animateList = [1, 2, 3, 4, 5]; export default class ReactReveal extends Component { render() { return ( <Fragment> {animateList.map((item, key) => ( <div style={styles.block} key={key}> <Fade top> <h1 style={styles.title}>{`block ${item}`}</h1> </Fade> </div> ))} </Fragment> ); } } const styles = { block: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%', height: '100%', background: '#000', borderBottom: '1px solid rgba(255,255,255,.2)', }, title: { textAlign: 'center', fontSize: 100, color: '#fff', fontFamily: 'Lato, sans-serif', fontWeight: 100, }, };
Sekarang kami memperkenalkan animateList konstan. Array mencakup lima elemen. Setelah menggunakan metode susunan peta, dimungkinkan untuk merender elemen apa pun dalam komponen Fade dengan memasukkan elemen ke dalam header. Gaya yang didefinisikan dalam konstanta gaya mendapatkan gaya CSS pendek untuk blok dan header. Di atas adalah lima blok dengan animasi Fade.
TweenOne dan animasi di Ant Design
Ant Design adalah perpustakaan UI Bereaksi yang berisi sejumlah besar komponen yang berguna dan mudah digunakan. Sangat cocok jika Anda perlu membuat antarmuka pengguna yang elegan. Dikembangkan oleh Alibaba, yang menggunakan perpustakaan di banyak proyeknya.

Contohnya memiliki beberapa komponen animasi. Kebanyakan dari mereka memiliki animasi yang serupa, jadi implementasi contoh akan lebih sederhana daripada yang di atas. Ini hanya akan mencakup bola, bola hijau dan elemen tambahan, misalnya, kotak merah.

Animasi ini menggunakan komponen TweenOne, yang membutuhkan PathPlugin untuk mengatur lintasan dengan benar. Semua ini hanya akan berfungsi jika ditempatkan
PathPlugin di TweenOne.plugins.
TweenOne.plugins.push(PathPlugin);
Opsi animasi utama adalah sebagai berikut:
- durasi - waktu animasi dalam ms;
- kemudahan - kelancaran animasi;
- yoyo - perubahan gerakan maju dan mundur dengan setiap pengulangan;
- repeat - repeat the animation. Anda perlu menggunakan -1 untuk animasi tanpa akhir;
- p - koordinat jalur untuk animasi;
- easyPath - koordinat jalur halus untuk animasi.
Dua parameter terakhir sangat spesifik, tetapi jangan khawatir, semuanya berfungsi sebagaimana mestinya.
const duration = 7000; const ease = 'easeInOutSine'; const p = 'M123.5,89.5 C148,82.5 239.5,48.5 230,17.5 C220.5,-13.5 127,6 99.5,13.5 C72,21 -9.5,56.5 1.5,84.5 C12.5,112.5 99,96.5 123.5,89.5 Z'; const easePath = 'M0,100 C7.33333333,89 14.3333333,81.6666667 21,78 C25.3601456,75.6019199 29.8706084,72.9026327 33,70 C37.0478723,66.2454406 39.3980801,62.0758689 42.5,57 C48,46.5 61.5,32.5 70,28 C77.5,23.5 81.5,20 86.5,16 C89.8333333,13.3333333 94.3333333,8 100,0'; const loop = { yoyo: true, repeat: -1, duration, ease, };
Sekarang Anda dapat mulai membuat objek animasi.
- redSquare berisi parameter loop ditambah koordinat Y, durasi, dan penundaan.
- greenBall berisi lintasan dengan parameter objek x, y - nilai p. Selain itu, durasi, pengulangan, dan kehalusan adalah fungsi dari TweenOne.easing.path, yang memiliki dua parameter.
- path - easyPath.
- lengthPixel adalah kurva yang dibagi menjadi hanya 400 bagian.
- track - oval dengan sumbu, memiliki gaya siklus dan parameter rotasi.
const animate = { redSquare: { ...loop, y: 15, duration: 3000, delay: 200, }, greenBall: { path: { x: p, y: p }, duration: 5000, repeat: -1, ease: TweenOne.easing.path(easePath, { lengthPixel: 400 }), }, track: { ...loop, rotate: 15, }, };
Anda juga perlu memperhatikan komponen TweenOne. Semua komponen akan diimpor dari rc-tween-one. TweenOne adalah komponen dasar dengan alat peraga dasar dan alat peraga animasi, yang merupakan animasi. Setiap TweenOne memiliki parameter animasi sendiri, seperti redSquare, track, greenBall.
import React from 'react'; import TweenOne from 'rc-tween-one'; export default function BannerImage() { return ( <div className="wrapper-ant-design"> <svg width="482px" height="500px" viewBox="0 0 482 500"> <defs> <path d="M151,55 C129.666667,62.6666667 116,74.3333333 110,90 C104,105.666667 103,118.5 107,128.5 L225.5,96 C219.833333,79 209.666667,67 195,60 C180.333333,53 165.666667,51.3333333 151,55 L137,0 L306.5,6.5 L306.5,156 L227,187.5 L61.5,191 C4.5,175 -12.6666667,147.833333 10,109.5 C32.6666667,71.1666667 75,34.6666667 137,0 L151,55 Z" id="mask" /> </defs> <g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd" transform="translate(0, 30)"> <g id="Group-13" transform="translate(0.000000, 41.000000)"> <TweenOne component="g" animation={animate.redSquare}> <rect stroke="#F5222D" strokeWidth="1.6" transform="translate(184.000000, 18.000000) rotate(8.000000) translate(-184.000000, -18.000000) " x="176.8" y="150.8" width="14.4" height="14.4" rx="3.6" /> </TweenOne> </g> <g id="Group-14" transform="translate(150.000000, 230.000000)"> <g id="Group-22" transform="translate(62.000000, 7.000000)"> <image id="cc4" alt="globe" xlinkHref="https://gw.alipayobjects.com/zos/rmsportal/FpKOqFadwoFFIZFExjaf.png" width="151px" height="234px" /> </g> <mask id="mask-2"> <use xlinkHref="#mask" fill="white" transform="translate(-42, -33)" /> </mask> <g mask="url(#mask-2)"> <TweenOne component="g" animation={animate.track} style={{ transformOrigin: '122.7px 58px' }}> <g transform="translate(-16, -52)"> <g transform="translate(16, 52)"> <path d="M83.1700911,35.9320015 C63.5256194,37.9279025 44.419492,43.1766434 25.8517088,51.6782243 C14.3939956,57.7126276 7.77167019,64.8449292 7.77167019,72.4866248 C7.77167019,94.1920145 61.1993389,111.787709 127.105708,111.787709 C193.012078,111.787709 246.439746,94.1920145 246.439746,72.4866248 C246.439746,55.2822262 212.872939,40.6598106 166.13127,35.3351955" id="line-s" stroke="#0D1A26" strokeWidth="1.35" strokeLinecap="round" transform="translate(127.105708, 73.561453) rotate(-16.000000) translate(-127.105708, -73.561453) " /> </g> <TweenOne component="g" animation={animate.greenBall}> <image alt="globe" id="id2" xlinkHref="https://gw.alipayobjects.com/zos/rmsportal/IauKICnGjGnotJBEyCRK.png" x="16" y="62" width="26px" height="26px" /> </TweenOne> </g> </TweenOne> </g> </g> </g> </svg> </div> ); }
7.77167019,64.8449292 7.77167019,72.4866248 C7.77167019,94.1920145 61.1993389,111.787709 127.105708,111.787709 C193.012078,111.787709 246.439746,94.1920145 246,439746 import React from 'react'; import TweenOne from 'rc-tween-one'; export default function BannerImage() { return ( <div className="wrapper-ant-design"> <svg width="482px" height="500px" viewBox="0 0 482 500"> <defs> <path d="M151,55 C129.666667,62.6666667 116,74.3333333 110,90 C104,105.666667 103,118.5 107,128.5 L225.5,96 C219.833333,79 209.666667,67 195,60 C180.333333,53 165.666667,51.3333333 151,55 L137,0 L306.5,6.5 L306.5,156 L227,187.5 L61.5,191 C4.5,175 -12.6666667,147.833333 10,109.5 C32.6666667,71.1666667 75,34.6666667 137,0 L151,55 Z" id="mask" /> </defs> <g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd" transform="translate(0, 30)"> <g id="Group-13" transform="translate(0.000000, 41.000000)"> <TweenOne component="g" animation={animate.redSquare}> <rect stroke="#F5222D" strokeWidth="1.6" transform="translate(184.000000, 18.000000) rotate(8.000000) translate(-184.000000, -18.000000) " x="176.8" y="150.8" width="14.4" height="14.4" rx="3.6" /> </TweenOne> </g> <g id="Group-14" transform="translate(150.000000, 230.000000)"> <g id="Group-22" transform="translate(62.000000, 7.000000)"> <image id="cc4" alt="globe" xlinkHref="https://gw.alipayobjects.com/zos/rmsportal/FpKOqFadwoFFIZFExjaf.png" width="151px" height="234px" /> </g> <mask id="mask-2"> <use xlinkHref="#mask" fill="white" transform="translate(-42, -33)" /> </mask> <g mask="url(#mask-2)"> <TweenOne component="g" animation={animate.track} style={{ transformOrigin: '122.7px 58px' }}> <g transform="translate(-16, -52)"> <g transform="translate(16, 52)"> <path d="M83.1700911,35.9320015 C63.5256194,37.9279025 44.419492,43.1766434 25.8517088,51.6782243 C14.3939956,57.7126276 7.77167019,64.8449292 7.77167019,72.4866248 C7.77167019,94.1920145 61.1993389,111.787709 127.105708,111.787709 C193.012078,111.787709 246.439746,94.1920145 246.439746,72.4866248 C246.439746,55.2822262 212.872939,40.6598106 166.13127,35.3351955" id="line-s" stroke="#0D1A26" strokeWidth="1.35" strokeLinecap="round" transform="translate(127.105708, 73.561453) rotate(-16.000000) translate(-127.105708, -73.561453) " /> </g> <TweenOne component="g" animation={animate.greenBall}> <image alt="globe" id="id2" xlinkHref="https://gw.alipayobjects.com/zos/rmsportal/IauKICnGjGnotJBEyCRK.png" x="16" y="62" width="26px" height="26px" /> </TweenOne> </g> </TweenOne> </g> </g> </g> </svg> </div> ); }

Ya, itu terlihat menakutkan, tetapi animasi menggunakan metode ini sederhana.
<TweenOne component="g" animation={animate.redSquare} /> <TweenOne component="g" animation={animate.track} /> <TweenOne component="g" animation={animate.greenBall} />
Yang perlu Anda lakukan adalah menjelaskan aturan animasi dan mentransfernya ke komponen TweenOne.
Untuk mencapai tujuan yang berbeda, diperlukan berbagai pendekatan. Artikel ini membahas beberapa solusi yang dapat digunakan dalam sejumlah besar proyek. Bisnis Anda adalah memilih yang tepat.
Skillbox merekomendasikan: