Help us understand the problem. What is going on with this article?

Material-UIでアニメーション

More than 1 year has passed since last update.

ReactのUIフレームワークとして有名なMaterial-UI(v4)でCSSアニメーションを行います。
withStyle内にクラスとしてcss transitionおよびcss animationを定義できます。

css transition

参考:Custom CSS transitions with React Material UI

css transitionを定義するにはtheme.transitions.createを使います。
第一引数には変化するCSS属性を指定します。第二引数にはアニメーション時間を指定します。

RainbowButton.jsx
import React from 'react'
import { withStyles } from '@material-ui/core'
import Button from '@material-ui/core/Button'

const RainbowButton = withStyles(theme => ({
  root: {
    color: theme.palette.common.white,
    fontWeight: 'bold',
    textShadow: `2px 2px 4px ${theme.palette.common.black}`,
    fontSize: 32,
    background: 'linear-gradient(100deg, red, yellow, lightgreen, aqua, blue, pink, magenta)',
    filter: 'saturate(90%)',
    transition: theme.transitions.create(
      ['opacity'],
      { duration: theme.transitions.duration.complex }
    ),
    '&:hover': {
      opacity: 0.7,
    },
  },
}))(({classes, className, ...props}) => <Button className={[classes.root, className].join(' ')} {...props} />)

export default RainbowButton

マウスオーバーすると半透明になります。

画面収録-2019-08-18-20.10.05.gif

css animation

$アニメーション名でアニメーション名を指定します。
MUI-v4以前の場合は$をつけません。

New.jsx
import React from 'react'
import { withStyles } from '@material-ui/styles'
import { red } from '@material-ui/core/colors'

let New = ({children, classes}) => (
  <div className={classes.root}>
    <div className={classes.new}>New</div>
    {children}
  </div>
)

New = withStyles((theme) => ({
  root: {
    position: 'relative',
  },
  new: {
    position: 'absolute',
    top: -20,
    left: 0,
    color: red[500],
    fontSize: 24,
    fontWeight: 'bold',
    transform: 'rotateZ(15deg)',
    textShadow:
    `1px 1px 0.5px ${theme.palette.grey[300]},
    -1px 1px 0.5px ${theme.palette.grey[300]},
    1px -1px 0.5px ${theme.palette.grey[300]},
    -1px -1px 0.5px ${theme.palette.grey[300]}`,
    animation: '$newAnimation 1s ease infinite alternate',
  },
  '@keyframes newAnimation': {
    '0%': {transform: 'rotateZ(-15deg) scale(1.0)'},
    '100%': {transform: 'rotateZ(-15deg) scale(1.3)'},
  },
}))(New)

export default New

Newの文字がアニメーションします。

画面収録-2019-08-18-20.11.31.gif

withStyleにprops経由でパラメータを渡す

v4からpropsからの情報をwithStyleで参照できるようになりました。
次のようにアロー関数の戻り値形式で指定します。
opacity: props => props.opacity || 0.8,

RainbowButton2.jsx
import React from 'react'
import { withStyles } from '@material-ui/core'
import Button from '@material-ui/core/Button'

const RainbowButton = withStyles(theme => ({
  root: {
    color: theme.palette.common.white,
    fontWeight: 'bold',
    textShadow: `2px 2px 4px ${theme.palette.common.black}`,
    fontSize: 32,
    background: 'linear-gradient(100deg, red, yellow, lightgreen, aqua, blue, pink, magenta)',
    filter: 'saturate(90%)',
    transition: theme.transitions.create(
      ['opacity'],
      { duration: theme.transitions.duration.complex }
    ),
    '&:hover': {
      opacity: props => props.opacity || 0.8,
    },
  },
}))(({classes, className, ...props}) => <Button className={[classes.root, className].join(' ')} {...props} />)

export default RainbowButton
teradonburi
気管支喘息を患って死にかけです。 いつ死ぬかわかりません。 成人喘息は誰でもなりえるものだし、 咳喘息から気管支喘息に進行すると慢性的な死の危険があるものです。 自身や周りで数週間咳が続いてる人がいたら気をつけて・・・ Twitterフォローいただけたらフォロバします。 https://twitter.com/teradonburi
meetsmore
プロを探せる見積りプラットフォーム「ミツモア」の開発・運営
https://meetsmore.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away