#javascript #reactjs #countdown #react-spring
Вопрос:
я создаю анимированный Flipclock для задачи кодирования в react.js использование react-пружины.
Я создал анимацию, и теперь мне нужно определить триггер, когда запускать анимацию. Прямо сейчас он работает постоянно, как вы можете видеть здесь:
https://flipcard-countdown.vercel.app/
Каждая карта за день, час, минуту, секунду-это один и тот же компонент реакции, который получает два реквизита:
- мера: Строка с названием меры времени
- время: Число со значением для отображения
Я использую react-spring, поэтому могу использовать логическое значение для определения того, выполняется ли анимация.
Мой план состоял в том, чтобы проверить, меняется ли целое число, которое я получаю с помощью реквизитов, каждую секунду, сравнивая его с тем же целым числом 1 сек назад. Если он изменится, выполните анимацию, если нет … вы поняли мою идею.
Однако я не знаю, как это сделать. Моя первоначальная идея с использованием setTimeout() не сработала.
Есть ли способ сохранить значение из временной опоры на одну секунду и сравнить его с новейшим экземпляром времени?
Вот код компонента: И репозиторий (если представляет какой-либо интерес): https://github.com/janhenrikfock/flipcard-countdown/tree/animation
export default function Flipcard({ measure, time }) {
Flipcard.propTypes = {
measure: PropTypes.string,
time: PropTypes.number,
}
const [previousNumber, setPreviousNumber] = useState(time)
useEffect(() => {
setPreviousNumber(time 1)
}, [time])
const frontCardAnimation = useSpring({
from: { transform: 'rotateX(0deg)' },
to: { transform: 'rotateX(-180deg)' },
// Change the cancel boolean to determine if the animation runs
cancel: false,
delay: 1,
config: config.slow,
reset: true,
})
const backCardAnimation = useSpring({
from: { transform: 'rotateX(180deg)' },
to: { transform: 'rotateX(0deg)' },
// Change the cancel boolean to determine if the animation runs
cancel: false,
delay: 1,
config: config.slow,
reset: true,
})
return (
<ContainerCard>
<StaticCardTop>
<span>{time}</span>
</StaticCardTop>
<StaticCardBottom>
<span>{previousNumber}</span>
</StaticCardBottom>
<AnimatedCardFront style={frontCardAnimation}>
<span>{previousNumber}</span>
</AnimatedCardFront>
<AnimatedCardBack style={backCardAnimation}>
<span>{time}</span>
</AnimatedCardBack>
<Subtext>{measure}</Subtext>
</ContainerCard>
)
}
Заранее спасибо всем, кто нашел время взглянуть на это! 🙏
Приветствую Яна Хенрика
Ответ №1:
В итоге я ввел другое состояние использования [cancelAnimation, setCancelAnimation], чтобы запустить анимацию таким образом. Это надежно запускает анимацию в нужный момент.
Я надеялся использовать предыдущий номер в качестве триггера И отображаемое значение, когда карта переворачивается, но сейчас для этого требуется другое решение, так как способ, которым я установил предыдущий номер, не всегда корректен.
export default function Flipcard({ measure, time }) {
const [displayedNumber, setDisplayedNumber] = useState(time)
const [previousNumber, setPreviousNumber] = useState()
const [cancelAnimation, setCancelAnimation] = useState(false)
useEffect(() => {
if (time === displayedNumber) {
setCancelAnimation(false)
setPreviousNumber(time)
} else {
setDisplayedNumber(time)
setPreviousNumber(time - 1)
setCancelAnimation(true)
}
}, [time, displayedNumber])
const frontCardAnimation = useSpring({
from: { transform: 'rotateX(0deg)' },
to: { transform: 'rotateX(-180deg)' },
delay: 1,
config: config.slow,
reset: cancelAnimation,
})
const backCardAnimation = useSpring({
from: { transform: 'rotateX(180deg)' },
to: { transform: 'rotateX(0deg)' },
delay: 1,
config: config.slow,
reset: cancelAnimation,
})
return (
<ContainerCard>
<StaticCardTop>
<span>{displayedNumber}</span>
</StaticCardTop>
<StaticCardBottom>
<span>{previousNumber}</span>
</StaticCardBottom>
<AnimatedCardFront style={frontCardAnimation}>
<span>{previousNumber}</span>
</AnimatedCardFront>
<AnimatedCardBack style={backCardAnimation}>
<span>{displayedNumber}</span>
</AnimatedCardBack>
<Subtext>{measure}</Subtext>
</ContainerCard>
)
}