Как добавить анимацию при изменении состояния в реакции? - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть следующий код, который меняет состояние через 3 секунды. Я пытаюсь добавить анимацию при изменении состояния. Я сделал отдельную анимацию, но у меня возникла проблема с соединением обоих. Моя анимация -

<div class="wave wave5"></div>
<div class="wave wave4"></div>
<div class="wave wave3"></div>
<div class="wave wave2"></div>
<div class="wave wave1"></div>
<div class="wave wave0"></div>
--------------------------------
.wave{
  position:absolute;
  top:calc((100% - 30px)/2);
  left:calc((100% - 30px)/2);
  width:30px;
  height:30px;
  background: url('https://c4.wallpaperflare.com/wallpaper/755/29/195/chun-lo-tiger-japanese-art-samurai-demon-hd-wallpaper-thumb.jpg');
  background-attachment:fixed;
  background-position:center center;
}
.wave0{
  z-index:2;
  background-size:auto 106%;
  animation:w 1s forwards;
}
.wave1{
  z-index:3;
  background-size:auto 102%;
  animation:w 1s .2s forwards;
}
.wave2{
  z-index:4;
  background-size:auto 104%;
  animation:w 1s .4s forwards;
}
.wave3{
  z-index:5;
  background-size:auto 101%;
  animation:w 1s .5s forwards;
}
.wave4{
  z-index:6;
  background-size:auto 102%;
  animation:w 1s .8s forwards;
}
.wave5{
  z-index:7;
  background-size:auto 100%;
  animation:w 1s 1s forwards;
}
@keyframes w{
  0%{
    top:calc((100% - 30px)/2);
    left:calc((100% - 30px)/2);
    width:30px;
    height:30px;
  }
  100%{
    top:calc((100% - 300px)/2);
    left:calc((100% - 300px)/2);
    width:300px;
    height:300px;
  }
}

Компонент приложения

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      images: [
        "https://picsum.photos/200/300/?image=523",
        "https://picsum.photos/200/300/?image=524",
        "https://picsum.photos/200/300/?image=525",
        "https://picsum.photos/200/300/?image=526"
      ],
      selectedImage: "https://picsum.photos/200/300/?image=523",
      in: 0
    };
  }

  componentDidMount() {
    setInterval(() => {
      this.setState(prevState => {
        if (prevState.in === 3) {
          return {
            in: 0,
            selectedImage: this.state.images[0]
          };
        } else {
          return {
            in: prevState.in + 1,
            selectedImage: this.state.images[prevState.in + 1]
          };
        }
      });
    }, 3000);
  }

  render() {
    return (
      <div className="App">
        <img  src={this.state.selectedImage} />
      </div>
    );
  }
}

Код - https://codesandbox.io/s/react-image-change-0eduy?fontsize=14&hidenavigation=1&theme=dark

Анимация - https://codepen.io/354erytu/pen/OJVNYKQ

1 Ответ

0 голосов
/ 20 февраля 2020

Вы пытаетесь использовать состояние для повторного рендеринга css в DOM для информации, которая уже имеется в DOM. Вы должны использовать хитрость в предоставлении нового css при каждом рендере, , но один css ничего не менять на визуальном только имя класса в DOM.

Вы можете найти код здесь: https://codesandbox.io/s/optimistic-tharp-j4px4?fontsize=14&hidenavigation=1&theme=dark

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      in: 0,
      enableWave: true
    };
  }

  componentDidMount() {
    setInterval(() => {
      this.setState(prevState => {
        if (prevState.in % 2 === 0) {
          return {
            in: prevState.in + 1,
            enableWave: false
          };
        } else {
          return {
            in: prevState.in + 1,
            enableWave: true
          };
        }
      });
    }, 1500);
  }

  render() {
    return (
      <div>
        <div style={{ display: this.state.enableWave ? "block" : "none" }}>
          <div className="wave wave5" />
          <div className="wave wave4" />
          <div className="wave wave3" />
          <div className="wave wave2" />
          <div className="wave wave1" />
          <div className="wave wave0" />
        </div>
      </div>
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...