onClick动画在React.js中只能运行一次

时间:2017-10-14 21:35:23

标签: javascript reactjs animation

我想在React.js中制作一个类似的游戏: https://www.youtube.com/watch?v=LfgyRk2QpJw

这是我到目前为止所做的: https://door-game.netlify.com/

以下是关键代码:

class App extends Component { 

getComponent(event) {
  event.currentTarget.style.animation = 'App-logo-spin 2s linear';
}   

render() {    
   return (
    <div className="App">
      <header className="App-header">

        <div className="App-logo" alt="logo" onClick=
        {this.getComponent.bind(this)}>

        <div className="little-circle one"></div>
        <div className="little-circle two"></div>
        <div className="little-circle three"></div>
        <div className="little-circle four"></div>

      </div>

现在onClick只工作一次,我怎样才能让它无限次地工作?

3 个答案:

答案 0 :(得分:0)

var appLogos = document.getElementsByClassName('App-logo');
var currentElement;

for (var i = 0, len = appLogos.length; i < len; i++) {
  appLogos[i].addEventListener('click', animate, false);
}

function animate(e) {
  currentElement = e.currentTarget;
  currentElement.style.animation = 'unset';
  setTimeout(function() {run(currentElement)}, 100);
}

function run(el) {
  el.style.animation = 'App-logo-spin 2s linear';
}
body {
  margin: 0;
  padding: 0;
  font-family: sans-serif
}

.App {
  text-align: center
}

.App-logo {
  height: 80px;
  width: 80px;
  background: #fff;
  border-radius: 50%;
  z-index: 2;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: stretch;
  align-items: stretch;
  -ms-flex-pack: justify;
  justify-content: space-between;
  position: relative;
  cursor: pointer
}

.App-logo-animation: {
  -webkit-animation: App-logo-spin 2s linear;
  animation: App-logo-spin 2s linear
}

.App-header {
  background-color: #222;
  height: 200px;
  padding: 20px;
  color: #fff;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: center;
  justify-content: center;
  -ms-flex-align: center;
  align-items: center;
  position: relative
}

.big-logo {
  height: 120px;
  width: 120px;
  background: red;
  z-index: 1
}

.big-logo,
.biggest-logo {
  position: absolute;
  border-radius: 50%
}

.biggest-logo {
  height: 150px;
  width: 150px;
  background: blue;
  z-index: 0
}

.little-circle {
  width: 10px;
  height: 10px;
  background-color: green;
  border-radius: 50%
}

.App-title {
  font-size: 1.5em
}

.App-intro {
  font-size: large
}

.four,
.one,
.three,
.two {
  position: absolute
}

.one {
  top: 15px;
  left: 15px
}

.two {
  top: 15px;
  right: 15px
}

.three {
  bottom: 15px;
  right: 15px
}

.four {
  bottom: 15px;
  left: 15px
}

.un {
  top: 20px;
  left: 20px
}

.dos {
  top: 20px;
  right: 20px
}

.tres {
  bottom: 20px;
  right: 20px
}

.quatro {
  bottom: 20px;
  left: 20px
}

.ein {
  top: 22px;
  left: 22px
}

.zwei {
  top: 22px;
  right: 22px
}

.drei {
  bottom: 22px;
  right: 22px
}

.fier {
  bottom: 22px;
  left: 22px
}

.submit {
  width: 60px;
  height: 60px;
  position: absolute;
  bottom: 140px;
  background-color: #8a2be2;
  cursor: pointer;
  border-radius: 50%
}

@-webkit-keyframes App-logo-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg)
  }
  to {
    -webkit-transform: rotate(1turn);
    transform: rotate(1turn)
  }
}

@keyframes App-logo-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg)
  }
  to {
    -webkit-transform: rotate(1turn);
    transform: rotate(1turn)
  }
}


/*# sourceMappingURL=main.ea098249.css.map*/
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
  <meta name="theme-color" content="#000000">
  <title>React App</title>
</head>

<body><noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root">
    <div class="App">
      <header class="App-header">
        <div class="App-logo" alt="logo">
          <div class="little-circle one"></div>
          <div class="little-circle two"></div>
          <div class="little-circle three"></div>
          <div class="little-circle four"></div>
        </div>
        <div class="App-logo big-logo" alt="logo">
          <div class="little-circle one un"></div>
          <div class="little-circle two dos"></div>
          <div class="little-circle three tres"></div>
          <div class="little-circle four quatro"></div>
        </div>
        <div class="App-logo biggest-logo" alt="logo">
          <div class="little-circle one ein"></div>
          <div class="little-circle two zwei"></div>
          <div class="little-circle three drei"></div>
          <div class="little-circle four fier"></div>
        </div>
      </header>
    </div>
  </div>
</body>

</html>

多次触发onClick()函数。

enter image description here

(此处6表示我点击li元素和onClick功能的次数已被触发。)

但是你要为你的部门设置css动画而不重置它。

在设置之前,请在每次点击时重置动画。它应该工作。

最初的建议只能在控制台上运行:

getComponent(event) {
    event.currentTarget.style.animation = 'unset';
    event.currentTarget.style.animation = 'App-logo-spin 2s linear';
} 

这不起作用,因为这两个语句的执行速度太快,实际上并没有生效。

这就是需要超时的原因,如上面的工作代码所示。

答案 1 :(得分:0)

我认为Neil提供了一个很好的解决方案,如果你想让旋转动画无限时间工作,这里我将提供一个你可能会觉得有用的不同解决方案,并且更加接近youtube视频中的效果。

我将使用来自animation的{​​{1}}而不是rotateZ()来实现相同的效果,而且您​​还可以设置每次点击的旋转度

流程是:

  1. 将当前的旋转度存储在该状态。
  2. 使用点击处理程序更新状态。
  3. 根据transform中的状态更新圈子样式。
  4. 以下是codepen:https://codepen.io/anon/pen/pWxjEE

    希望这会有所帮助:)

答案 2 :(得分:0)

你在这里遇到的问题是,基本上css动画依赖于看到“嘿,有一个动画标志添加到一个元素”来知道动画。作为Neil,建议删除它并重新添加它似乎它将完成 BUT 的工作,当你将它设置为“”并再一次添加一行时,监视动画标志的过程只是没有注意到它已经消失了。所以它继续认为它一直存在。

CSS Tricks -Restarting an Animation

中已经很好地描述了这种情况

文章的妙语是你的unlick功能看起来像

getComponent(event) {
    event.currentTarget.style = ' ';
    void event.currentTarget.offsetWidth;
    event.currentTarget.style.animation = 'App-logo-spin 2s linear';
} 

我已经尽可能地从静态js中测试了这段代码并使其正常工作,所以我希望它能在App.js文件中运行。