React - постепенное исчезновение div, пауза и исчезновение div - PullRequest
0 голосов
/ 16 июня 2020

В моем приложении React я пытаюсь постепенно добавить div, немного подождать и снова убрать его. Все работает отлично, кроме затухания. Мой S CSS выглядит так:

$orange-color: #DD7C15;
$white-color: #FFFFFF;
$black-color: #222222;

.App {
  font-family: sans-serif;
  text-align: center;
}

.message-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 100000;
  width: 100vw;
  color: $orange-color;
  font-size: 4em;
  text-align: center;
  background-color: $white-color;
  border: 2px solid $black-color;
  opacity: 0.9;
  animation: fadeIn 2s ease-in;

  &.hide {
    opacity: 0;
    animation: fadeOut 2s ease-out;
  }
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 0.9;
  }
}

@keyframes fadeOut {
  0% {
    opacity: 0.9;
  }
  100% {
    opacity: 0;
  }
}

И мой соответствующий код React:

const showBanner = () => {
    setMessageBannerText("My sweet awesome banner!!");
    setTimeout(() => {
      setMessageBannerText("");
    }, 3000);
  };

  const bannerClasses =
    messageBannerText === "" ? "message-banner hide" : "message-banner";

Я создал песочницу, показывающую, о чем я говорю. https://codesandbox.io/s/brave-grass-q1y6j

Ответы [ 2 ]

2 голосов
/ 16 июня 2020

Проблема:

Анимация работает нормально, но вы удаляете содержимое setMessageBannerText(""); во время анимации, поэтому его не видно


Решение:

Таким образом, вместо того, чтобы делать содержимое пустым, вы должны поддерживать состояние для анимации

1) Решение:

const steps = {
  0: "", // <--- blank coz message-banner has animation itself
  1: "message-banner",
  2: "message-banner hide"
};

export default function App() {
  const messageBannerText = "My sweet awesome banner!!";
  const [animationStep, setAnimationStep] = useState(0);

  const showBanner = () => {
    setAnimationStep(1);
    setTimeout(() => {
      // setMessageBannerText(""); // <---- issue
      setAnimationStep(2);
    }, 3000);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={showBanner}>Show Banner</button>
      <MessageBanner text={messageBannerText} classes={steps[animationStep]} />
    </div>
  );
}

РАБОЧАЯ ДЕМО:

Edit #SO-animate-issue2


2) Решение: (с css изменениями, но вам все равно нужно следуйте указанным выше изменениям)

.message-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 100000;
  width: 100vw;
  color: $orange-color;
  font-size: 4em;
  text-align: center;
  background-color: $white-color;
  border: 2px solid $black-color;
  opacity: 0;

  &.animate {
    opacity: 0;
    animation: fadeInOut 5s ease-out;
  }
}

// single animation for fade in and fade out
@keyframes fadeInOut {
  0% {
    opacity: 0;
  }
  30% {
    opacity: 0.9;
  }
  70% {
    opacity: 0.9;
  }
  100% {
    opacity: 0;
  }
}
  const [show, setShow] = useState(false);

  const showBanner = () => {
    if (!show) { // <--- just for safe side, if animation is going on, then ignore state change
      setShow(true);
      setTimeout(() => {
        setShow(false);
      }, 5000);
    }
  };

  const bannerClasses = show ? "message-banner animate" : "message-banner";

РАБОЧАЯ ДЕМО:

Edit #SO-animate-issue

1 голос
/ 16 июня 2020

Привет, я отредактировал вашу песочницу, чтобы добиться желаемого результата: -

Edit vigilant-water-x135f

Изменения: -

1) Добавлено show и hide классы.

2) Введено логическое состояние для перехода, а не зависимости от текста, потому что ваш message-banner div не имеет собственной высоты или ширины. Мы просто позволим тексту оставаться, но скрыть div от пользователя.

3) Вместо animation используется transition, так как вы просто переключаетесь между двумя состояниями и хотите придерживаться этих для остальной части вашего приложения. С анимацией вам придется проделать еще несколько уловок, чтобы они закрепились. Плюс animation полезен для более сложных сценариев.

...