我正在尝试使用 React / Typescript 创建一个呼吸应用程序。我不想使用 React Native。
我有呼吸圈设置为组件,我有它自己的动画设置每个圈,如果它有一个(我不提供这个 code,因为这不是问题)
我遇到的麻烦是让动画无限运行,同时保持 setTimeout()的延迟。
import React, { useState, useEffect } from "react";
import "./App.css";
import {
BreatheInCircle,
BreatheHoldInCircle,
BreatheOutCircle,
BreatheHoldOutCircle,
} from "./BreatheCircle";
const circles = [
<BreatheInCircle/>,
<BreatheHoldInCircle />,
<BreatheOutCircle />,
<BreatheHoldOutCircle />,
];
const App = () => {
const [circleArray] = useState(circles);
const [displayElement, setDisplayElement] = useState(<div></div>);
const [index, setIndex] = useState(0);
useEffect(() => {
setTimeout(() => {
setDisplayElement(circleArray[index]);
setIndex(index + 1);
}, 4000);
});
return (
<div>
{displayElement}
</div>
);
}
export default App;`enter code here`
当我现在运行这个,它会为每个组件运行一次 useEffect,然后停止。我需要动画重复,直到我停止它。
EDIT我能够解决我遇到的延迟问题,但我仍然需要帮助循环。
const App = () => {
const [circleArray] = useState(circles);
const [displayElement, setDisplayElement] = useState(<div></div>);
const [index, setIndex] = useState(0);
const timeoutDelays = [0, 4000, 4000, 4000, 4000];
const changeCircle = () => {
setCircle(circles[index]);
setIndex(index + 1);
};
useEffect(() => {
setTimeout(changeCircle, timeoutDelays[index]);
}, [index]);
如果 setInterval 仍然是一个解决方案,我想知道如何实现它。现在,它运行一次,然后停止。
为什么你想超时,而不是间隔?也从父子组件发送一些数据来更新动画这是不重要的,我认为。
是我用来解决它的最终代码。它使用的是 setInterval,我只需要正确地做到这一点。我 upvoted user8119020 的答案,因为他们引导我解决这个问题的正确方法。
const BreatheCircles: FC = () => {
const [circle, setCircle] = useState(<div></div>);
const [index, setIndex] = useState(0);
const circles = [
<BreatheInCircle />,
<BreatheHoldInCircle />,
<BreatheOutCircle />,
<BreatheHoldOutCircle />,
];
const changeCircle = () => {
setCircle(circles[index]);
setIndex(index + 1);
if(index >= 3) {
setIndex(0);
}
};
useEffect(() => {
const interval = setInterval(changeCircle, 4000);
return () => clearInterval(interval);
}, [changeCircle]);
return <>{circle}</>;
};
动画开始之前有一个延迟,但这不是问题。再次感谢 user8119020 的帮助。
UPDATE**大家好,我知道这是有点后,但我找到了一个更好的方法来使用纯 CSS 来做到这一点,是我用来创建相同的呼吸功能而不需要重新渲染一百万次的代码示例。
我使用 MUI 来创建样式。
const breatheCircles = makeStyles((theme: Theme) =>
createStyles({
breatheCircle: {
borderRadius: '50%',
width: '30vh',
height: '30vh',
animation: '$breathe 17400ms infinite',
},
'@keyframes breathe': {
'0%': {
transform: 'scale(.5)',
backgroundColor: '#71A1C9',
},
'24.9%': {
backgroundColor: '#71A1C9',
},
'25%': {
transform: 'scale(1)',
},
'25.1%': {
backgroundColor: '#FF9833',
},
'50%': {
transform: 'scale(1)',
backgroundColor: '#FF9833',
},
'50.1%': {
backgroundColor: '#000000',
},
'75%': {
transform: 'scale(.5)',
backgroundColor: '#000000',
},
'75.1%': {
backgroundColor: '#FF9833',
},
'100%': {
transform: 'scale(.5)',
backgroundColor: '#FF9833',
},
},
})
);
const Breathe: FC = () => {
const cl = useStyles();
const circleStyles = breatheCircles();
const gender = useSelector<State>((state) => state.gender);
return (
<>
<Header />
<div className={cl.root}>//styled elsewhere
<div className={cl.circles}>//styled elsewhere
<div className={circleStyles.breatheCircle} />
<Counter />
</div>
<div className={cl.onBar}>
<ButtonBar />
</div>
</div>
</>
);
};
我只是认为社区希望看到一种更有效的方式来动画这些圈子。
非常感谢。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(57条)