繁体   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