反应模式的下滑动画

问题描述 投票:0回答:2

我已经在react和css中实现了一个模态,目前,当我打开它时,我实现了一个向上滑动的动画,其中模态从底部向上滑动,但是当我关闭它时我希望它向下滑动,我不能要弄清楚如何准确创建下滑动画,有人可以帮忙吗? 代码=>

import "./styles.css";
import react, { useState } from "react";

export default function App() {
  const [isModalOpen, setIsModalOpen] = useState(false);

  return (
    <div>
      <button onClick={() => setIsModalOpen(true)}>open </button>
      {isModalOpen && (
        <div className={`modal-overlay`}>
          <div className={`modal-content`}>
            <div className="feedbackModalHeader">
              <img
                src="/assets/dislike_modal.svg"
                alt=""
                className="dislikeBtnNonFilled"
              />
              <p className="provideFeedback">Provide additional feedback</p>
            </div>
            <button onClick={() => setIsModalOpen(false)}> close </button>
          </div>
        </div>
      )}
    </div>
  );
}

CSS代码=>

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  transition: opacity 0.3s ease;
}

* {
  max-width: 100%;
}

.modal-content {
  background: #f5f0f0;
  padding: 20px;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
  z-index: 999;
  transform: translateY(100%);
  animation: slide-up 0.3s ease-out forwards;
  width: 59rem;
  border-radius: 8px;
  margin-left: auto;
  margin-right: auto;
  box-shadow: 0 4px 20px 0 rgb(0 0 0 / 10%), 0 1px 2px 0 rgb(0 0 0 / 6%);
  height: 21rem;
  position: relative;
  left: 2rem;
}

@keyframes slide-up {
  from {
    transform: translateY(100%);
  }

  to {
    transform: translateY(0);
  }
}

.close-button {
  position: absolute;
  top: 10px;
  right: 10px;
  border: none;
  background: transparent;
  font-size: 24px;
  cursor: pointer;
}

.provideFeedback {
  font-size: 20px;
}

.feedbackModalHeader {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  margin-top: 0.8rem;
}

代码沙盒链接=> https://codesandbox.io/s/dark-river-6ckllv?file=/src/styles.css

css reactjs modal-dialog css-animations css-transitions
2个回答
1
投票

您必须根据状态更改模式的类。 (条件类名

这是一种使用您想要的东西创建模态的简单方法:

首先,定义CSS动画:

.modal-slide-down {
  animation-name: slide-down;
  animation-duration: 0.5s;
  animation-fill-mode: forwards;
}

@keyframes slide-down {
  0% {
    transform: translateY(-100%);
    opacity: 0;
  }
  100% {
    transform: translateY(0);
    opacity: 1;
  }
}

然后,在您的 React 组件中,添加一个状态变量来跟踪模式是否应该打开或关闭:

const [isOpen, setIsOpen] = useState(false);

当用户单击按钮或执行其他操作来打开模式时,将 isOpen 状态设置为 true:

<button onClick={() => setIsOpen(true)}>Open Modal</button>

最后,根据 isOpen 状态有条件地将 CSS 类应用到模态:

<div className={`modal ${isOpen ? 'modal-slide-down' : ''}`}>
  {/* Modal content goes here */}
</div>

更多解释:

isOpen
状态为true时,
modal-slide-down
类被添加到模态组件中,从而触发向下滑动动画。当
isOpen
状态为 false 时,移除
modal-slide-down
类,从而触发上滑动画。

通过这些更改,模式将在打开时向下滑动到视图中,并在关闭时向上滑动回来。当然,您可能需要调整动画持续时间和其他 CSS 属性以适合您的特定用例。

我希望我能够解决您的问题。


0
投票

基于用户20459171的答案。您需要一个有条件的类名。然而,由于您是从屏幕中心开始到底部,因此变换从 0% 到 100%。正确的CSS是这样的:

.modal-overlay {
position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  transition: opacity 0.3s ease;
}

* {
  max-width: 100%;
}

.modal-content {
  background: #f5f0f0;
  padding: 20px;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
  z-index: 999;
  transform: translateY(100%);
  width: 59rem;
  border-radius: 8px;
  margin-left: auto;
  margin-right: auto;
  box-shadow:
    0 4px 20px 0 rgb(0 0 0 / 10%),
    0 1px 2px 0 rgb(0 0 0 / 6%);
  height: 21rem;
  position: relative;
  left: 2rem;
}

.modal-content.slide-down {
  animation: slide-down 0.5s ease-in-out forwards;
}

.modal-content.slide-up {
  animation: slide-up 0.5s ease-out forwards;
}

@keyframes slide-down {
  from {
    transform: translateY(0%);
    opacity: 1;
  }
  to {
    transform: translateY(100%);
    opacity: 0;
  }
}

@keyframes slide-up {
  from {
    transform: translateY(100%);
    opacity: 0;
  }
  to {
    transform: translateY(0%);
    opacity: 1;
  }
}

.close-button {
  position: absolute;
  top: 10px;
  right: 10px;
  border: none;
  background: transparent;
  font-size: 24px;
  cursor: pointer;
}

.provideFeedback {
  font-size: 20px;
}

.feedbackModalHeader {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  margin-top: 0.8rem;
}

我已将动画代码分离到其自己的类名中。一种用于上升,一种用于下降。正如我之前提到的,我添加了 @keyframes 下拉菜单以及正确的从和到过渡。这是 app.js 文件。

    import "./styles.css";
    import react, { useState } from "react";
    
    export default function App() {
        const [isModalOpen, setIsModalOpen] = useState(false);
        //This useState Hook sets the animation to the correct direction
        const [modalAnimation, setModalAnimation] = useState("slide-up");
    
        function close() {
            setModalAnimation("slide-down");
            setTimeout(() => {
                setIsModalOpen(false);
                // Sets it for the next time so it slides up when called
                setModalAnimation("slide-up");
            }, 600);
        }
    
        return (
            <div>
                <button onClick={() => setIsModalOpen(true)}>open </button>
                {isModalOpen && (
                    <div className={`modal-overlay`}>
                        <div className={`modal-content ${modalAnimation}`}>
                            <div className="feedbackModalHeader">
                                <img
                                    src="/assets/dislike_modal.svg"
                                    alt=""
                                    className="dislikeBtnNonFilled"
                                />
                                <p className="provideFeedback">Provide additional feedback</p>
                            </div>
                            <button onClick={() => close()}> close </button>
                        </div>
                    </div>
                )}
                   
            </div>
        );
    }

我还把超时设置为600ms,这样就流畅多了。

© www.soinside.com 2019 - 2024. All rights reserved.