[英]I am trying to animate an array of letters in my React Hangman App
我正在尝试使用 react-spring 让来自数组的字母为我的 Hangman 应用程序进出动画。 我希望它们在加载时淡入,并在从阵列中移除时淡出。 单击时它们会从阵列中删除。 现在我只想让它们淡入淡出。 我得到的最接近的是和以前一样的按钮,但它很迟钝,根本没有动画。
我尝试过使用 Spring 组件、Transition 组件和 useTransition。
这是我试图解决的最新示例。 密码箱
const App = () => {
const [availableLetters, setAvailableLetters] = useState([
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z'
])
const location = useLocation()
const transitions = useTransition(location, location => location.pathname, {
from: { opacity: 0, transform: 'translate(100%,0)' },
enter: { opacity: 1, transform: 'translate(0,0)' },
leave: { opacity: 0, transform: 'translate(-50%,0)' }
})
return (
<Fragment>
<Header defaultGuesses={defaultGuesses} />
{msgAlerts.map((msgAlert, index) => (
<AutoDismissAlert
key={index}
heading={msgAlert.heading}
variant={msgAlert.variant}
message={msgAlert.message}
/>
))}
{/* routes */}
<main className="container">
{transitions.map(({ item, props, key }) => (
<animated.div native='true' key={key} style={props}>
<Switch location={item}>
{/* home */}
<Route
exact
path="/"
render={() => (
<Welcome
msgAlert={msgAlert}
resetAllButSecret={resetAllButSecret}
setSecret={setSecret}
/>
)}
/>
<Route
exact
path="/guesses"
render={() => (
<Guesses
msgAlert={msgAlert}
secret={secret}
setGuesses={setGuesses}
resetAllButSecretAndGuesses={resetAllButSecretAndGuesses}
setDefaultGuesses={setDefaultGuesses}
/>
)}
/>
<Route
exact
path="/play"
render={() => (
<Play
guesses={guesses}
availableLetters={availableLetters}
correctLetters={correctLetters}
incorrectLetters={incorrectLetters}
secret={secret}
setSecret={setSecret}
pushToCorrect={pushToCorrect}
pushToIncorrect={pushToIncorrect}
removeAvailable={removeAvailable}
msgAlert={msgAlert}
resetBoard={resetBoard}
gameOver={gameOver}
setGameOver={setGameOver}
setGuesses={setGuesses}
resetGame={resetGame}
/>
)}
/>
</Switch>
</animated.div>
))}
</main>
</Fragment>
)
}
export default App
import { Spring, animated, Transition } from 'react-spring/renderprops'
import ClickableLetter from './ClickableLetter'
const AnimatedLetter = animated(ClickableLetter)
const Play = ({'tons of props i'm not showing'}) => {
const availHTML = availableLetters.map((letter, index) => (
<Transition
from={{ opacity: 0 }}
to={{ opacity: 1 }}
leave={{ opacity: 0 }}
// config={config.slow}
key={`${letter}_${index}`}
>
{styles => (
<AnimatedLetter
style={styles}
pushToCorrect={pushToCorrect}
pushToIncorrect={pushToIncorrect}
secret={secret}
removeAvailable={removeAvailable}
letter={letter}
gameOver={gameOver}
msgAlert={msgAlert}
/>
)}
</Transition>
))
return (
<AbsoluteWrapper>
<Fragment>
{availHTML}
</Fragment>
</AbsoluteWrapper>
)
}
const availHtml = availableLetters.map(letter => (
<ClickableLetter
key={letter}
pushToCorrect={pushToCorrect}
pushToIncorrect={pushToIncorrect}
secret={secret}
removeAvailable={removeAvailable}
letter={letter}
gameOver={gameOver}
msgAlert={msgAlert}
/>
))
import React from 'react'
import { withRouter } from 'react-router-dom'
import { PrimaryButton } from '../Shared/Styled'
// these are the green letters used to let a user guess a letter
const ClickableLetter = ({
letter, secret, pushToCorrect, pushToIncorrect, removeAvailable, gameOver, msgAlert
}) => {
// this function is used to either push the value to a correct or incorrect array causing an app wide state change and re render
const pushValue = () => {
if (!gameOver) {
if (secret.toLowerCase().includes(letter)) {
pushToCorrect(letter)
} else {
pushToIncorrect(letter)
}
// take it from the availLetter arr to re-render this component with one less letter
removeAvailable(letter)
} else {
msgAlert({
heading: 'Oops!',
message: 'Game is over, please click reset to play again',
variant: 'danger'
})
}
}
return (
<PrimaryButton onClick={pushValue}>{letter}</PrimaryButton>
)
}
export default withRouter(ClickableLetter)
const transitions = useTransition(availableLetters, item => item, {
from: { opacity: 0},
enter: { opacity: 1},
leave: { opacity: 0}
})
const availHTML = transitions.map(({ item, props, key }) =>
<AnimatedLetter key={key} style={props}
pushToCorrect={pushToCorrect}
pushToIncorrect={pushToIncorrect}
secret={secret}
removeAvailable={removeAvailable}
letter={item}
gameOver={gameOver}
msgAlert={msgAlert}/>
)
我的另一个尝试是使用动画.div 而不是动画(ClickableLetter),ClickableLetter 呈现在 div 内。 像这样的东西。 (没有代码所以这不准确)
const availHTML = transitions.map(({ item, props, key }) =>
<animated.div key={key} style={props}><ClickableButton letter={item}/> </animated.div>
))
好吧,过了一会儿我想通了。 首先,我需要准备好我的自定义组件 animation...
const AnimatedClickableLetter = animated(ClickableLetter)
然后我使用了Transition组件,我仍然没有弄清楚如何使用useTransition来做到这一点。 我试过了,但没有成功。
const availHTML = (
<Transition
items={availableLetters} // the array
keys={item => item} //unique keys, in this instance, the letter is fine
from={{ opacity: 1 }} // animation props
enter={{ opacity: 1 }}
leave={{ opacity: 0 }}
>
{letter => props => //for each letter, make an AnimatedClickableLetter..
//props will be the animation style.
<AnimatedClickableLetter
style={props} //here's where we pass it in as props.
pushToCorrect={pushToCorrect}
pushToIncorrect={pushToIncorrect}
secret={secret}
removeAvailable={removeAvailable}
letter={letter}
gameOver={gameOver}
msgAlert={msgAlert}
/>
}
</Transition>
)
最后,让我永远弄清楚的步骤......将样式添加到自定义组件本身。
const ClickableLetter = ({
letter, secret, pushToCorrect, pushToIncorrect, removeAvailable, gameOver, msgAlert, style //accept the prop here...
}) => {
// this function is used to either push the value to a correct or incorrect array causing an app wide state change and re render
const pushValue = () => {
if (!gameOver) {
if (secret.toLowerCase().includes(letter)) {
pushToCorrect(letter)
} else {
pushToIncorrect(letter)
}
// take it from the availLetter arr to re-render this component with one less letter
removeAvailable(letter)
} else {
msgAlert({
heading: 'Oops!',
message: 'Game is over, please click reset to play again',
variant: 'danger'
})
}
}
return (
// add the style to the button, here.
<Fragment>
- <PrimaryButton onClick={pushValue}>{letter}</PrimaryButton>
+ <PrimaryButton style={style} onClick={pushValue}>{letter}</PrimaryButton>
</Fragment>
)
}
export default ClickableLetter
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.