この記事では、Reactに最適なアニメーションフレームワークの1つである ReactSpringについて説明します。 コンポーネントのスタイリングをスムーズな物理ベースの遷移に変更する背後にあるいくつかの基本を学びます。

前提条件

React SpringにはフックベースのAPIとコンポーネントベースのAPIの両方があり、すべてのアニメーションで基本的な状態のフックを使用することだけを検討します。 したがって、React Hooksをブラッシュアップする必要がある場合は、この記事をお勧めします。

インストールとセットアップ

もちろん、react-springが必要になるので、 Create ReactAppを使用して開始できます。

$ npx create-react-app react-spring-example
$ cd react-spring-example
$ npm i react-spring 

開始と終了

App.jsファイルでは、react-springuseSpringanimatedが必要になります。

useSpringは、スタイルを設定できるカスタムフックであり、fromtoの値を持つオブジェクトを開始状態と終了状態として受け取り、react-springがそれらの間の移行。 fromtoは、色、サイズ、変換、さらにはスクロールバーなど、ほぼすべてのcssプロパティのオブジェクトを取得できます。 春のアニメーションを適用するには、HTMLタグにanimatedを追加し、アニメーションをスタイルに渡す必要があります。 デフォルトでは、これはコンポーネントがマウントされるとすぐに実行されます。

ある値から別の値に移動するのは少し退屈かもしれませんが、react-springを使用すると、配列を使用して複数のステージでアニメーションをレンダリングできます。 追加するプロパティには、常に開始状態を含めることを忘れないでください。

App.js
import React, { useState } from 'react';
import { useSpring, animated } from 'react-spring';


const App = () => {
  const animation = useSpring({
    from: { opacity: 0 },
    to: { opacity: 1 }
  });

  const colorAnimation = useSpring({
    from: { color: 'blue' },
    to: { color: `rgb(255,0,0)` }
  });

  const multiAnimation = useSpring({
    from: { opacity: 0, color: 'red' },
    to: [
        { opacity: 1, color: '#ffaaee' },
        { opacity: 1, color: 'red' },
        { opacity: .5, color: '#008000' },
        { opacity: .8, color: 'black' }
    ]
  });
  return (
    <div>
      <animated.h1 style={animation}>Hello World</animated.h1>
      <animated.h1 style={colorAnimation}>Hello World</animated.h1>
      <animated.h1 style={multiAnimation}>Hello World</animated.h1>
    </div>
  )
};

export default App;

ローカル状態を追加すると、マウント時に遷移する代わりに、アニメーションに実際のインタラクションを追加できるようになります。 fromtoの代わりに、シングルステップアニメーションに三項演算子を使用できます。

App.js
import React, { useState } from 'react';

const App = () => {
  const [on, toggle] = useState(false);

  const animation = useSpring({
    color: on ? 'blue' : 'red'
  });
  return (
    <div>
      <animated.h1 style={animation}>{!on ? "I'm red" : "Now I'm blue" }</animated.h1>
      <button onClick={() => toggle(!on)}>Change</button>
    </div>
  )
};

補間する

要素とコンポーネントに静的なスタイルの変更を追加するだけでなく、interpolateメソッドを使用してより面白くて再利用可能なアニメーションを作成できます。 スプリングもオブジェクトであるため、変数をスプリングに追加し、interpolateを使用してスタイル用に変数を抽出できます。

春から値を抽出し、interpolateを使用してさらに構造を解除し、テンプレートリテラルにそれらを投入するだけで、準備は完了です。 これにより、x位置に基づくカラー値など、より動的な値を自由に設定できるようになります。

App.js
const App = () => {
  const [on, toggle] = useState(false);

  const { xy } = useSpring({
    from: { xy: [0, 0], c: 'green' },
    xy: on ? [800, 200] : [0, 0],
    c: on ? 'red' : 'green'
  });
  return (
    <div>
      <animated.h1
        style={{ 
            transform: xy.interpolate((x, y) => `translate(${x}px, ${y}px)`), 
            color: c.interpolate(c => c)}}>
        {!on ? "I'm here" : "Now I'm over here"}</animated.h1>
      <button onClick={() => toggle(!on)}>Change</button>
    </div>
  )
};

キーフレームの模倣

interpolateのより便利な側面の1つは、CSSキーフレームをエミュレートできることです。 スプリングに値を渡す代わりに、1または0に設定します。 以前のように補間する前に、rangeoutputを使用してオブジェクトを渡す必要があります。 範囲は0から1までの任意の値にすることができ、CSSキーフレームでブレークポイントを設定するように機能します。対応する出力は、事前にレンダリングされる値です。

2番目のinterpolateは、出力が変更されるたびにスタイルをリセットします。

App.js
const App = () => {
  const [on, toggle] = useState(false)

  const { x, c } = useSpring({
    from: { xy: [0, 0], c: 0 },
    x: on ? 1 : 0,
    c: on ? 1 : 0
  })

  return ( 
    <div>
      <animated.h1
        style={{
          transform: x.interpolate({
            range: [0, .25, .5, .75, 1],
            output: [0, 500, 200, 800, 500]
          }).interpolate(x => `translateX(${x}px)`),

          color: c.interpolate({
            range: [0, .5, 1],
            output: ['red', 'blue', 'green']
          }).interpolate(c => c)
        }}>
        {!on ? "I'm here" : "Now don't know where I'm going"}</animated.h1>
      <button onClick={() => toggle(!on)}>Change</button>
    </div>
  )
}

構成

それ自体、前の例は非常に突然で耳障りです。 これは、react-springのデフォルト構成が原因です。 アニメーションは主に、春に簡単に操作できるいくつかのプロパティに基づいています。 docs には、さまざまなプロパティを直感的に理解するのに役立つ、すばらしいインタラクティブな例があります。

  • mass:速度とトランジションをオーバーシュートする距離に影響します。
  • tension:全体のベロシティに影響します。
  • friction:抵抗と減速速度を制御します。
  • clamp:トランジションをオーバーシュートする必要があるかどうか。
App.js
const animation = useSpring({
    {/* ... */}
    config: {
      mass: 5,
      tension: 50,
      friction: 25,
      clamp: true
    }
  });

react-springのチームを支援するために、インポートできる構成プリセットもいくつか含まれています。これは非常に便利です。

  • config.default {質量:1、張力:170、摩擦:26}
  • config.gentle {質量:1、張力:120、摩擦:14}
  • config.wobbly {質量:1、張力:180、摩擦:12}
  • config.stiff {質量:1、張力:210、摩擦:20}
  • config.slow {質量:1、張力:280、摩擦:60}
  • config.molasses {質量:1、張力:280、摩擦:120}
App.js
import { useSpring, animated, config } from 'react-spring';

const animation = useSpring({
    {/* ... */}
    config: config.wobbly
  });

// Or you can just destructure it if you want to change other options 
const animation = useSpring({
    {/* ... */}
    config: {
        ...config.molasses, 
        clamp: true
    }
  });

結論

ここでの例は最も派手ではなかったかもしれませんが、react-springを使用したReactアニメーションの背後にある基本を理解するのに十分であることを願っています。 ✨