如何在React中使用keyframes实现模态框关闭时的下滑动画
解决方案
1. 修正CSS代码
你当前的下滑关键帧逻辑写反了,0%对应动画起始状态,100%对应结束状态,同时要补充动画结束后保持最终状态的配置,还要把公共样式抽到基础.modal类,避免切换类时样式丢失:
/* 基础模态框样式,公共属性统一抽离 */ .modal { margin: auto; top: 10%; position: fixed; z-index: 999; height: 100%; } .toDisplayModal{ animation: slideup 0.3s ease forwards; } .toCloseModal { animation: slidedown 0.3s ease forwards; } @keyframes slideup { 0% { transform: translateY(400px); animation-timing-function: ease-out; } 60% { transform: translateY(20px); animation-timing-function: ease-in; } 80% { transform: translateY(10px); animation-timing-function: ease-out; } 100% { transform: translateY(0px); } } @keyframes slidedown { /* 动画起始:模态框正常展示的位置 */ 0% { transform: translateY(0px); animation-timing-function: ease-out; } 20% { transform: translateY(10px); animation-timing-function: ease-in; } 40% { transform: translateY(20px); animation-timing-function: ease-out; } /* 动画结束:完全滑出可视区域 */ 100% { transform: translateY(400px); } }
animation-fill-mode: forwards的作用是让动画播放完成后保持最后一帧的状态,避免动画结束后回弹到初始位置。
2. 修正React状态逻辑
核心问题是不能点击关闭后直接隐藏/卸载模态框,要等下滑动画播放完成后再执行隐藏操作,逻辑参考如下:
import { useState } from 'react' import classnames from 'classnames' // 组件内部逻辑 const [showModal, setShowModal] = useState(false) const [closeModal, setCloseModal] = useState(false) // 关闭按钮触发方法 const handleClose = () => { // 先添加关闭动画类触发下滑效果 setCloseModal(true) // 等待动画播放完成(时长和CSS中配置的0.3s保持一致) setTimeout(() => { setShowModal(false) // 重置关闭状态,方便下次打开模态框时正常触发上滑动画 setCloseModal(false) }, 300) } // 渲染逻辑 return ( <> <button onClick={() => setShowModal(true)}>打开模态框</button> {showModal && ( <div className={classnames(styles.modal, { [styles.toDisplayModal]: showModal && !closeModal, [styles.toCloseModal]: closeModal, })} > <div className={styles.container}> <CloseButton onClick={handleClose} /> <div> text </div> </div> </div> )} </> )
内容的提问来源于stack exchange,提问作者RandomDeveloper
相关产品推荐
相关产品推荐

