簡體   English   中英

我正在嘗試在我的 React Hangman App 中為一組字母設置動畫

[英]I am trying to animate an array of letters in my React Hangman App

問題

我正在嘗試使用 react-spring 讓來自數組的字母為我的 Hangman 應用程序進出動畫。 我希望它們在加載時淡入,並在從陣列中移除時淡出。 單擊時它們會從陣列中刪除。 現在我只想讓它們淡入淡出。 我得到的最接近的是和以前一樣的按鈕,但它很遲鈍,根本沒有動畫。

我嘗試過使用 Spring 組件、Transition 組件和 useTransition。

這是我試圖解決的最新示例。 密碼箱

APP --- 沒有包含所有的 useState 函數或輔助函數以提高可讀性

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

相關 Play.js 代碼。 這就是我現在正在嘗試的,但什么都沒有出現,根本沒有字母

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}
    />
  ))

ClickableLetter.js

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM