React Hooks 从 onMouseLeave 淡出模态效果
React Hooks fade out effect on modal from onMouseLeave
这对大多数人来说应该是一件容易的事。从按钮(由 onMouseEnter 触发)打开后的模态 window 需要在触发 onMouseLeave 后淡出效果。模态“绿色方块”根本不应该移动它的位置,而只是在它触发 onMouseLeave 或 setOpenFalse 时淡出。他们的风格顺风顺水 css。提前致谢 ☠️
沙盒在这里 - https://codesandbox.io/s/modal-transition-clicked-1egnp?file=/src/styles.css:0-191
import React from "react";
import classNames from "classnames";
import { useState, Fragment } from "react";
import { useBoolean } from "./hooks/useBoolean";
import "./styles.css";
export const Actions = ({ defaultSelected = "like" }) => {
const [selected, setSelected] = useState(defaultSelected);
const [isOpen, setOpenTrue, setOpenFalse] = useBoolean();
return (
<div className="relative rounded">
<button
onMouseEnter={setOpenTrue}
onMouseLeave={setOpenFalse}
className={classNames("flex items-center gap-2 rounded px-2 py-1", {
"": isOpen
})}
>
{selected && <Fragment>open modal</Fragment>}
{isOpen && (
<div className="absolute mt-20 left-0 flex justify-center items start h-12">
<div className="bg-green-700 w-24 h-36 shadow grid grid-flow-col px-2 py-1 gap-2 animate-mount"></div>
</div>
)}
</button>
</div>
);
};
export default Actions;
.animate-mount {
animation: mount 0.4s linear;
}
@keyframes mount {
0% {
opacity: 0;
transform: translateY(50%);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
有点micromanage-y,但您可以再添加两个状态来跟踪按钮元素何时进入和退出。
- 设置模态打开并在鼠标输入时设置输入,在鼠标离开时设置输入 false,设置退出时为真,然后设置超时以随后设置打开和退出为假。
- 创建一个
.animate-unmount
仅对不透明度设置动画的动画。
卸载动画和 setTimeout
的持续时间应该大致相同。
styles.css
.animate-mount {
animation: mount 0.4s linear;
}
@keyframes mount {
0% {
opacity: 0;
transform: translateY(50%);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.animate-unmount {
animation: unmount 0.5s ease-in-out;
}
@keyframes unmount {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
Reactions.js
export const Actions = ({ defaultSelected = "like" }) => {
const [selected, setSelected] = useState(defaultSelected);
const [isOpen, setOpenTrue, setOpenFalse] = useBoolean();
const [isEntered, setEnteredTrue, setEnteredFalse] = useBoolean();
const [isExited, setExitedTrue, setExitedFalse] = useBoolean();
return (
<div className="relative rounded">
<button
onMouseEnter={() => {
setOpenTrue();
setEnteredTrue();
}}
onMouseLeave={() => {
setEnteredFalse();
setExitedTrue();
setTimeout(() => {
setOpenFalse();
setExitedFalse();
}, 500);
}}
className={classNames("flex items-center gap-2 rounded px-2 py-1", {
"": isOpen
})}
>
{selected && <Fragment>open modal</Fragment>}
{isOpen && (
<div className="absolute mt-20 left-0 flex justify-center items start h-12">
<div
className={classNames(
"bg-green-700 w-24 h-36 shadow grid grid-flow-col px-2 py-1 gap-2",
{
"animate-mount": isEntered,
"animate-unmount": isExited
}
)}
></div>
</div>
)}
</button>
</div>
);
};
这对大多数人来说应该是一件容易的事。从按钮(由 onMouseEnter 触发)打开后的模态 window 需要在触发 onMouseLeave 后淡出效果。模态“绿色方块”根本不应该移动它的位置,而只是在它触发 onMouseLeave 或 setOpenFalse 时淡出。他们的风格顺风顺水 css。提前致谢 ☠️
沙盒在这里 - https://codesandbox.io/s/modal-transition-clicked-1egnp?file=/src/styles.css:0-191
import React from "react";
import classNames from "classnames";
import { useState, Fragment } from "react";
import { useBoolean } from "./hooks/useBoolean";
import "./styles.css";
export const Actions = ({ defaultSelected = "like" }) => {
const [selected, setSelected] = useState(defaultSelected);
const [isOpen, setOpenTrue, setOpenFalse] = useBoolean();
return (
<div className="relative rounded">
<button
onMouseEnter={setOpenTrue}
onMouseLeave={setOpenFalse}
className={classNames("flex items-center gap-2 rounded px-2 py-1", {
"": isOpen
})}
>
{selected && <Fragment>open modal</Fragment>}
{isOpen && (
<div className="absolute mt-20 left-0 flex justify-center items start h-12">
<div className="bg-green-700 w-24 h-36 shadow grid grid-flow-col px-2 py-1 gap-2 animate-mount"></div>
</div>
)}
</button>
</div>
);
};
export default Actions;
.animate-mount {
animation: mount 0.4s linear;
}
@keyframes mount {
0% {
opacity: 0;
transform: translateY(50%);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
有点micromanage-y,但您可以再添加两个状态来跟踪按钮元素何时进入和退出。
- 设置模态打开并在鼠标输入时设置输入,在鼠标离开时设置输入 false,设置退出时为真,然后设置超时以随后设置打开和退出为假。
- 创建一个
.animate-unmount
仅对不透明度设置动画的动画。
卸载动画和 setTimeout
的持续时间应该大致相同。
styles.css
.animate-mount {
animation: mount 0.4s linear;
}
@keyframes mount {
0% {
opacity: 0;
transform: translateY(50%);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.animate-unmount {
animation: unmount 0.5s ease-in-out;
}
@keyframes unmount {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
Reactions.js
export const Actions = ({ defaultSelected = "like" }) => {
const [selected, setSelected] = useState(defaultSelected);
const [isOpen, setOpenTrue, setOpenFalse] = useBoolean();
const [isEntered, setEnteredTrue, setEnteredFalse] = useBoolean();
const [isExited, setExitedTrue, setExitedFalse] = useBoolean();
return (
<div className="relative rounded">
<button
onMouseEnter={() => {
setOpenTrue();
setEnteredTrue();
}}
onMouseLeave={() => {
setEnteredFalse();
setExitedTrue();
setTimeout(() => {
setOpenFalse();
setExitedFalse();
}, 500);
}}
className={classNames("flex items-center gap-2 rounded px-2 py-1", {
"": isOpen
})}
>
{selected && <Fragment>open modal</Fragment>}
{isOpen && (
<div className="absolute mt-20 left-0 flex justify-center items start h-12">
<div
className={classNames(
"bg-green-700 w-24 h-36 shadow grid grid-flow-col px-2 py-1 gap-2",
{
"animate-mount": isEntered,
"animate-unmount": isExited
}
)}
></div>
</div>
)}
</button>
</div>
);
};