5 großartige Möglichkeiten, um React-Apps im Jahr 2019 zu animieren



Animation in React-Anwendungen ist ein beliebtes und diskutiertes Thema. Tatsache ist, dass es viele Möglichkeiten gibt, es zu erstellen. Einige Entwickler verwenden CSS, indem sie HTML-Klassen Tags hinzufügen. Toller Weg, es lohnt sich zu benutzen. Wenn Sie jedoch mit komplexen Arten von Animationen arbeiten möchten, sollten Sie sich die Zeit nehmen, GreenSock zu studieren. Es ist eine beliebte und leistungsstarke Plattform. Es gibt auch viele Bibliotheken und Komponenten zum Erstellen von Animationen. Reden wir über sie.

Dieser Artikel beschreibt fünf Möglichkeiten zum Animieren von React-Anwendungen:

  • CSS
  • ReactTransitionGroup;
  • Reaktionsanimationen
  • Reagieren-enthüllen;
  • TweenOne und Ant Design.

Skillbox empfiehlt: Der Online-Schulungskurs "Profession Java-Entwickler" .
Wir erinnern Sie daran: Für alle Leser von „Habr“ - ein Rabatt von 10.000 Rubel bei der Anmeldung für einen Skillbox-Kurs mit dem Aktionscode „Habr“.

Alle Beispiele sind im Repository verfügbar (von hier aus werden anstelle von Bildern wie im Originalartikel Quellen in den Artikel eingefügt).

CSS


Diese Methode wurde am Anfang erwähnt und ist wirklich gut. Wenn die Assembly klein ist, anstatt JavaScript-Bibliotheken zu importieren und zu verwenden, benötigt der Browser nicht viele Ressourcen. Dies wirkt sich natürlich auf die Anwendungsleistung aus. Wenn Ihre Animation relativ einfach sein sollte, achten Sie auf diese Methode.

Ein Beispiel ist ein animiertes Menü:



Es ist relativ einfach, mit einer CSS-Eigenschaft und einem Trigger wie className = "is-nav-open" für das HTML-Tag.

Es gibt verschiedene Möglichkeiten, diese Methode zu verwenden. Erstellen Sie beispielsweise einen Wrapper über der Navigation und rufen Sie dann Feldänderungen auf. Da die Navigation eine konstante Breite von 250 Pixel hat, sollte die Breite des Wrappers mit der Eigenschaft margin-left oder translateX dieselbe Breite haben. Wenn Sie die Navigation anzeigen müssen, fügen Sie className = "is-nav-open" für den Wrapper hinzu und verschieben Sie den Wrapper nach margin-left / translateX: 0;

Letztendlich sieht die Animationsquelle folgendermaßen aus:

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> ); } } 

Und hier sind die CSS-Stile:

 .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; } 

Ich wiederhole, wenn die Animation relativ einfach ist, dann ist diese Methode die Hauptmethode. Benutzer werden die Leistung des Browsers zu schätzen wissen.

ReactTransitionGroup


Die ReactTransitionGroup-Komponente wurde vom ReactJS-Community-Team entwickelt. Mit ihm können Sie einfach grundlegende CSS-Animationen und -Übergänge implementieren.

ReactTransitionGroup dient zum Ändern von Klassen beim Ändern des Komponentenlebenszyklus. Es hat eine geringe Größe und muss im Paket für die React-Anwendung installiert werden, wodurch sich die Gesamtgröße der Baugruppe geringfügig erhöht. Darüber hinaus können Sie CDN verwenden.

Die ReactTransitionGroup besteht aus drei Elementen: Transition, CSSTransition und TransitionGroup. Um die Animation in ihnen zu starten, müssen Sie die Komponente umbrechen. Der Stil muss wiederum in CSS-Klassen geschrieben werden.

Hier ist die Animation und dann die Art und Weise, sie zu implementieren.



Der erste Schritt besteht darin, die CSSTransitionGroup aus der React-Transition-Gruppe zu importieren. Danach müssen Sie die Liste umbrechen und die Eigenschaft TransitionName festlegen. Jedes Mal, wenn Sie ein untergeordnetes Element in einer CSSTransitionGroup hinzufügen oder entfernen, werden animierte Stile angezeigt.

 <CSSTransitionGroup transitionName="example"> {items} </CSSTransitionGroup> 

Beim Festlegen der Eigenschaft TransitionName = "example" müssen die Klassen in den Stylesheets mit dem Namen des Beispiels beginnen.

 .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; 

Oben sehen Sie ein Beispiel für die Verwendung von ReactTransitionGroup.

Sie benötigen außerdem Logik und zwei Methoden zum Implementieren des Beispiels zum Hinzufügen einer Kontaktliste.

Die erste handleAdd-Methode - sie fügt neue Kontakte hinzu, erhält einen zufälligen Namen, den sie dann in das Array state.items einfügt.

Verwenden Sie handleRemove, um einen Kontakt nach Index im Array state.items zu entfernen.

 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> ); } }; 

Animationen reagieren


React-Animations ist eine Bibliothek, die auf animate.css basiert. Es ist einfach damit zu arbeiten, sie hat viele verschiedene Animationssammlungen. Die Bibliothek ist mit jeder Inline-Bibliothek kompatibel, die die Verwendung von Objekten zum Definieren der Hauptrahmen einer Animation unterstützt, einschließlich Radium-, Aphrodite- oder Stilkomponenten.



Ich weiß was du denkst:



Lassen Sie uns nun am Beispiel einer Bounce-Animation sehen, wie dies funktioniert.



Importieren Sie zunächst die Animation aus Reaktionsanimationen.

const Bounce = styled.div`animation: 2s $ {keyframes` $ {bounce} `} infinite`;

Nach dem Erstellen der Komponente verpacken wir dann jeden HTML-Code oder jede HTML-Komponente für die Animation.

 <bounce><h1>Hello Animation Bounce</h1></bounce> 

Ein Beispiel:

 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> ); } } 

Alles funktioniert, die Animation ist sehr einfach. Darüber hinaus gibt es eine großartige Lösung für die Verwendung von Bounce-Animationen beim Scrollen - Reagieren- Animieren-beim-Scrollen.

Reagieren-enthüllen


Das React Reveal-Framework verfügt über grundlegende Animationen, einschließlich Überblenden, Reflektieren, Skalieren, Drehen und mehr. Es ermöglicht das Arbeiten mit allen Animationen mithilfe von Requisiten. Sie können also zusätzliche Einstellungen festlegen, einschließlich Position, Verzögerung, Entfernung, Kaskade und andere. Andere CSS-Effekte können verwendet werden, einschließlich serverseitiges Rendern und Komponenten höherer Ordnung. Wenn Sie eine Bildlaufanimation benötigen, sollten Sie im Allgemeinen dieses Framework verwenden.

 import Fade from 'react-reveal/Fade'; <Fade top> <h1>Title</h1> </Fade> 



Insgesamt gibt es fünf Blöcke, von denen jeder eine Vollbildseite und einen Titel hat.

 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, }, }; 

Jetzt führen wir die Konstante animateList ein. Das Array enthält fünf Elemente. Nach Verwendung der Map-Array-Methode ist es möglich, jedes Element in Fade-Komponenten zu rendern, indem Elemente in den Header eingefügt werden. Stile, die in der Stilkonstante definiert sind, erhalten kurze CSS-Stile sowohl für den Block als auch für den Header. Oben sind fünf Blöcke mit Fade-Animation.

TweenOne und Animation in Ant Design


Ant Design ist eine React UI-Bibliothek, die eine große Anzahl nützlicher und benutzerfreundlicher Komponenten enthält. Es ist geeignet, wenn Sie elegante Benutzeroberflächen erstellen müssen. Entwickelt von Alibaba, das die Bibliothek in vielen seiner Projekte nutzt.



Das Beispiel enthält einige animierte Komponenten. Die meisten von ihnen haben ähnliche Animationen, daher ist eine Beispielimplementierung einfacher als die oben beschriebene. Dies umfasst nur eine Kugel, eine grüne Kugel und ein zusätzliches Element, beispielsweise ein rotes Quadrat.



Die Animation verwendet die TweenOne-Komponente, die PathPlugin benötigt, um die Flugbahn korrekt festzulegen. All dies funktioniert nur, wenn es platziert wird
PathPlugin bei TweenOne.plugins.

 TweenOne.plugins.push(PathPlugin); 

Die wichtigsten Animationsoptionen lauten wie folgt:

  • Dauer - Animationszeit in ms;
  • Leichtigkeit - Glätte der Animation;
  • yoyo - Bewegungsänderung vorwärts und rückwärts bei jeder Wiederholung;
  • Wiederholen - Wiederholen Sie die Animation. Sie müssen -1 für endlose Animationen verwenden.
  • p - die Koordinaten des Pfades für die Animation;
  • easyPath - Koordinaten des glatten Pfades für die Animation.

Die letzten beiden Parameter sind sehr spezifisch, aber machen Sie sich keine Sorgen, alles funktioniert so, wie es sollte.

 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, }; 

Jetzt können Sie mit dem Erstellen des Animationsobjekts beginnen.

  • redSquare enthält die Schleifenparameter sowie die Y-Koordinate, die Dauer und die Verzögerung.
  • greenBall enthält den Pfad mit den Parametern des Objekts x, y - den Wert von p. Darüber hinaus sind Dauer, Wiederholung und Glätte eine Funktion von TweenOne.easing.path, das zwei Parameter hat.
  • Pfad - easyPath.
  • lengthPixel ist eine Kurve, die in nur 400 Abschnitte unterteilt ist.
  • Spur - ein Oval mit Achsen, es hat Zyklusstile und einen Rotationsparameter.

 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, }, }; 

Sie müssen auch auf die TweenOne-Komponente achten. Alle Komponenten werden aus rc-tween-one importiert. TweenOne ist eine grundlegende Komponente mit grundlegenden Eigenschaften und animierten Requisiten, die Animationen sind. Jeder TweenOne verfügt über eigene Animationsparameter wie redSquare, track und 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> ); } 



Ja, es sieht beängstigend aus, aber die Animation mit dieser Methode ist einfach.

  <TweenOne component="g" animation={animate.redSquare} /> <TweenOne component="g" animation={animate.track} /> <TweenOne component="g" animation={animate.greenBall} /> 

Sie müssen lediglich die Animationsregeln beschreiben und an die TweenOne-Komponente übertragen.

Um unterschiedliche Ziele zu erreichen, sind unterschiedliche Ansätze erforderlich. In diesem Artikel wurden verschiedene Lösungen untersucht, die in einer Vielzahl von Projekten verwendet werden können. Ihr Geschäft ist es, die richtige zu wählen.
Skillbox empfiehlt:

Source: https://habr.com/ru/post/de456972/


All Articles