7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Reactでkeyframes propertyを使ったアニメーション

Posted at

はじめに

最近いろいろなところでのReactの活用事例が増えてきています。Facebook、Instagramはもちろん、TwitterのモバイルviewもReactが使われています。
SPAを構築していくときに、必要になるのがアニメーションだと思っています。ユーザに対してしっかりとしたフィードバックがないと、何が起こったかがわかりづらいですよね。そこで、必要になるのがCSSのkeyframes propertyです。

そもそも、ReactでのCSSはいろいろ手法があると思います。世界中の素晴らしいエンジニアたちはいろいろなNPMモジュールを作成しています。CSS ModulesRadiumkeyframesのためのReact Componentを作っていたりします。

しかし、僕自身あまりCSSをシュッと構築できないので、CSSのファイルを用意してなんとかするタイプのものはあまりうまく使えないのです。しかも、ReactにはもともとInline Styleが用意されているので、それを存分に使った方が、いいのではないかと考えました。(ただし、CSSを綺麗に書ける方はCSS使った方が良さそうです。)

方法

単純です。CSSStyleSheet interfaceというWebAPIを利用します。
方針としては、<style>タグのDOMを作って、<head>要素の中に作ったDOMを追加します。そうすると追加した<style>タグのsheetというプロパティにCSSStyleSheetのインスタンスが入ります。そしてCSSStyleSheet#insertRule(rule, index)というメソッドを使って、keyframes propertyを定義してあげるという方法です。

例えば下記のような関数を定義してあげます。

injectStyle.js
const injectStyle = (style) => {
  const styleElement = document.createElement('style');
  let styleSheet = null;

  document.head.appendChild(styleElement);

  styleSheet = styleElement.sheet;

  styleSheet.insertRule(style, styleSheet.cssRules.length);
};

export default injectStyle;

そして、以下のようなComponentを作成します。

SampleComponent.js
import React from 'react';
import injectStyle from './path/to/injectStyle';

export default class SampleComponent extends React.Component {
  constructor(props) {
    super(props);
    
    const keyframesStyle = `
      @-webkit-keyframes pulse {
        0%   { background-color: #fecd6d; }
        25%  { background-color: #ef7b88; }
        50%  { background-color: #acdacf; }
        75%  { background-color: #87c3db; }
        100% { background-color: #fecd6d; }
      }
    `;
    injectStyle(keyframesStyle);
    
    this.state.style = {
      container: {
        WebkitAnimation: 'pulse 10s linear infinite',
      },
      title: {
        fontSize: '2rem',
      },
    }
  }

  render() {
    const { style } = this.state;
    
    return (
      <div style={style.container}>
        <h3 style={style.title}>Hello world using React!</h3>
      </div>
    );
  }
}

上記のようにすることで、Inline Styleを利用しながら、あまり方法がなかったkeyframes propertyを定義してアニメーションすることができます。

screencast 2016-06-20 01-22-04.gif

まとめ

試しに動かす分には十分な方法だと思いますが、おそらく大きなプロジェクトで使う場合には採用しない方がいいかもしれない方法です。そもそもCSS in JSという方法はあまり利用されていないのかもしれません。僕が知る限り、ほとんどのReactのプロジェクトではスタイルはCSSで定義して、CSS Modulesで適用することがほとんどだと思います。
僕が知っているCSS in JSを採用している大きなプロジェクトは、Material-UIというGoogleのマテリアルデザインをReactで実装したプロジェクトくらいです。

ただ、自分の中では結構Inline Styleが気に入っているので、できる方法がないか探してみた次第です。

このエントリのサンプルコードのGist https://gist.github.com/yamadayuki/f1ea9ccacad7f1c140457b5877fb54cc

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?