[英]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.