web-dev-qa-db-ja.com

Reactスタイル付きコンポーネントのフェードイン/フェードアウト

Reactコンポーネントを作成してフェードインとフェードアウトを処理しようとしています。次のコードで、outをプロップとしてコンポーネントに渡すと、次のように表示されますアニメーション化する前に非表示にします。デフォルトでフェードインさせ、outプロップを渡すとフェードアウトさせようとしています。この問題の解決策は誰かに表示されますか?

import React from 'react';
import styled, { keyframes } from 'styled-components';

const fadeIn = keyframes`
  from {
    transform: scale(.25);
    opacity: 0;
  }

  to {
    transform: scale(1);
    opacity: 1;
  }
`;

const fadeOut = keyframes`
  from {
    transform: scale(1);
    opacity: 0;
  }

  to {
    transform: scale(.25);
    opacity: 1;
  }
`;

const Fade = styled.div`
  ${props => props.out ?
    `display: none;`
   : `display: inline-block;`
   }
  animation: ${props => props.out ? fadeOut : fadeIn} 1s linear infinite;
`;

function App() {
  return (
    <div>
      <Fade>&lt;????test&gt;</Fade>
    </div>
  );
}

export default App;

WebpackBin実行例

13
Elliot

コードの問題は、props.outがtrueのときにdisplayプロパティをnoneに設定していることです。そのため、アニメーションが表示されないのは、その前にコンポーネントを非表示にしているためです。

フェードアウトアニメーションを行う方法は、代わりに可視性プロパティを使用し、アニメーションと同じ時間だけ可視性プロパティを遷移させることです。 (- this old SO answer を参照)

このような何かはあなたの問題を解決するはずです:

const Fade = styled.default.div`
  display: inline-block;
  visibility: ${props => props.out ? 'hidden' : 'visible'};
  animation: ${props => props.out ? fadeOut : fadeIn} 1s linear;
  transition: visibility 1s linear;
`;
const fadeIn = styled.keyframes`
  from {
    transform: scale(.25);
    opacity: 0;
  }

  to {
    transform: scale(1);
    opacity: 1;
  }
`;

const fadeOut = styled.keyframes`
  from {
    transform: scale(1);
    opacity: 1;
  }

  to {
    transform: scale(.25);
    opacity: 0;
  }
`;

const Fade = styled.default.div`
  display: inline-block;
  visibility: ${props => props.out ? 'hidden' : 'visible'};
  animation: ${props => props.out ? fadeOut : fadeIn} 1s linear;
  transition: visibility 1s linear;
`;

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      visible: true,
    }
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState({
        visible: false,
      })
    }, 1000)
  }

  render() {
    return (
      <div>
        <Fade out={!this.state.visible}>&lt;????test&gt;</Fade>
      </div>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>

<div id="root" />

注:フェードアウトアニメーションも不透明度が0から1になり、逆ではありませんでした。スニペットでも修正しました。

15
mxstbr