HTML 元素上的连续动画

发布于 2025-01-14 04:02:32 字数 4919 浏览 0 评论 0原文

伙计们。我试图通过按钮上的 css 类创建一组连续的“动画”,但我不断遇到一个问题,即我的所有按钮同时收到效果,而不是一个接一个。

函数 playAllSequence 应按照数组中存在的顺序依次突出显示每个按钮。

我已经尝试将 setTimeOut 函数放入闭包中,并尝试将声明更改为 let 而不是 var。

我缺少什么?

提前致谢

// Get number of buttons on the document
var numberOfButtons = document.querySelectorAll(".btn").length;
var collectionButtonsClicked = [];
var collectionOfRandomColors  = [];
var  buttonsColors = ["blue", "green", "red", "yellow"];
var gameTitle = document.querySelector("#level-title");

// detecting clicks on the buttons
for ( let i = 0; i < numberOfButtons; i++) {
  document.querySelectorAll(".btn")[i].addEventListener("click", function () {
    collectionButtonsClicked.push(this.id);
    // call click animation function
    clickAnimation ();
    // Only checks when arrays have the same length so the user have to click all the sequence again
    if (collectionButtonsClicked.length === collectionOfRandomColors.length) {
      checkClick();
    }
})};

// detecting button press to start the game
document.addEventListener("keydown", function (event) {
  if (event.key === "a") {
    gameTitle.innerHTML = "Game Started";
    generateRandomColor();
    playAllSequence();
  }
});

// check if the click is correct
function checkClick () {
  // if correct - Generate new color, disable buttons and play the sequence on all buttons
  let arrayRandomStringfied = JSON.stringify(collectionOfRandomColors);
  let arrayClickedStringfied = JSON.stringify(collectionButtonsClicked);

  if (arrayRandomStringfied === arrayClickedStringfied) {
    generateRandomColor();
    playAllSequence();
    console.log("acertou!")
    // erasing click array so the player has to click all the color again
    collectionButtonsClicked = [];
  } else {
    //call fail animation function
    failAnimation();
    // function to reset the arrays and the title
    restartGame();
    console.log("errou!")
  }
}

//Generate random color and return array - User will have to follow this colors
function generateRandomColor () {
  let randomIndex = Math.floor(Math.random() * 4);
  collectionOfRandomColors.push(buttonsColors[randomIndex]);
  return collectionOfRandomColors;
}

function playAllSequence () {
  // disabling all buttons
  for ( let i = 0; i < numberOfButtons; i++) {
    document.querySelectorAll(".btn")[i].disabled = true;
  }

  for ( let i = 0; i < collectionOfRandomColors.length; i++ ) {
    doSetTimeOut(i);
  }

  // Enabling all buttons again
  for ( let i = 0; i < numberOfButtons; i++) {
    document.querySelectorAll(".btn")[i].disabled = false;
  }
}

function doSetTimeOut (i) {
  let activeButton = document.querySelector("." + collectionOfRandomColors[i]);
  // Add pressed effect
  activeButton.classList.add("pressed");

  // Remove pressed effect after 1 second
  setTimeout(function() {
    activeButton.classList.remove("pressed")
  }, 1000);
}

function clickAnimation () {
}

function failAnimation () {
}

function restartGame () {
  collectionOfRandomColors = [];
  collectionButtonsClicked = [];
  gameTitle.innerHTML = "Press A key to Start";
}
body {
  text-align: center;
  background-color: #011F3F;
}

#level-title {
  font-family: 'Press Start 2P', cursive;
  font-size: 3rem;
  margin:  5%;
  color: #FEF2BF;
}

.container {
  display: block;
  width: 50%;
  margin: auto;
}

.btn {
  margin: 25px;
  display: inline-block;
  height: 200px;
  width: 200px;
  border: 10px solid black;
  border-radius: 20%;
}

.game-over {
  background-color: red;
  opacity: 0.8;
}

.red {
  background-color: red;
}

.green {
  background-color: green;
}

.blue {
  background-color: blue;
}

.yellow {
  background-color: yellow;
}

.pressed {
  box-shadow: 0 0 20px white;
  background-color: grey;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>Simon</title>
  <link rel="stylesheet" href="styles.css">
  <link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">
</head>

<body>
  <h1 id="level-title">Press A Key to Start</h1>
  <div class="container">
    <div class="row">

      <div type="button" id="green" class="btn green">

      </div>

      <div type="button" id="red" class="btn red">

      </div>
    </div>

    <div class="row">

      <div type="button" id="yellow" class="btn yellow">

      </div>
      <div type="button" id="blue" class="btn blue">

      </div>

    </div>

  </div>

  <script src="index.js" charset="utf-8"></script>
</body>

</html>

guys. I'm trying to create a group of sequential "animations" through css classes on my buttons, but i keep getting a problem where all my buttons receive the effect on the same time and not one after another.

The function playAllSequence should hightlight each button one after another following the sequence present in an array.

I've already tried to put the setTimeOut function inside a closure and tried changed my declaration to let instead of var.

What am i missing?

Thanks in advance

// Get number of buttons on the document
var numberOfButtons = document.querySelectorAll(".btn").length;
var collectionButtonsClicked = [];
var collectionOfRandomColors  = [];
var  buttonsColors = ["blue", "green", "red", "yellow"];
var gameTitle = document.querySelector("#level-title");

// detecting clicks on the buttons
for ( let i = 0; i < numberOfButtons; i++) {
  document.querySelectorAll(".btn")[i].addEventListener("click", function () {
    collectionButtonsClicked.push(this.id);
    // call click animation function
    clickAnimation ();
    // Only checks when arrays have the same length so the user have to click all the sequence again
    if (collectionButtonsClicked.length === collectionOfRandomColors.length) {
      checkClick();
    }
})};

// detecting button press to start the game
document.addEventListener("keydown", function (event) {
  if (event.key === "a") {
    gameTitle.innerHTML = "Game Started";
    generateRandomColor();
    playAllSequence();
  }
});

// check if the click is correct
function checkClick () {
  // if correct - Generate new color, disable buttons and play the sequence on all buttons
  let arrayRandomStringfied = JSON.stringify(collectionOfRandomColors);
  let arrayClickedStringfied = JSON.stringify(collectionButtonsClicked);

  if (arrayRandomStringfied === arrayClickedStringfied) {
    generateRandomColor();
    playAllSequence();
    console.log("acertou!")
    // erasing click array so the player has to click all the color again
    collectionButtonsClicked = [];
  } else {
    //call fail animation function
    failAnimation();
    // function to reset the arrays and the title
    restartGame();
    console.log("errou!")
  }
}

//Generate random color and return array - User will have to follow this colors
function generateRandomColor () {
  let randomIndex = Math.floor(Math.random() * 4);
  collectionOfRandomColors.push(buttonsColors[randomIndex]);
  return collectionOfRandomColors;
}

function playAllSequence () {
  // disabling all buttons
  for ( let i = 0; i < numberOfButtons; i++) {
    document.querySelectorAll(".btn")[i].disabled = true;
  }

  for ( let i = 0; i < collectionOfRandomColors.length; i++ ) {
    doSetTimeOut(i);
  }

  // Enabling all buttons again
  for ( let i = 0; i < numberOfButtons; i++) {
    document.querySelectorAll(".btn")[i].disabled = false;
  }
}

function doSetTimeOut (i) {
  let activeButton = document.querySelector("." + collectionOfRandomColors[i]);
  // Add pressed effect
  activeButton.classList.add("pressed");

  // Remove pressed effect after 1 second
  setTimeout(function() {
    activeButton.classList.remove("pressed")
  }, 1000);
}

function clickAnimation () {
}

function failAnimation () {
}

function restartGame () {
  collectionOfRandomColors = [];
  collectionButtonsClicked = [];
  gameTitle.innerHTML = "Press A key to Start";
}
body {
  text-align: center;
  background-color: #011F3F;
}

#level-title {
  font-family: 'Press Start 2P', cursive;
  font-size: 3rem;
  margin:  5%;
  color: #FEF2BF;
}

.container {
  display: block;
  width: 50%;
  margin: auto;
}

.btn {
  margin: 25px;
  display: inline-block;
  height: 200px;
  width: 200px;
  border: 10px solid black;
  border-radius: 20%;
}

.game-over {
  background-color: red;
  opacity: 0.8;
}

.red {
  background-color: red;
}

.green {
  background-color: green;
}

.blue {
  background-color: blue;
}

.yellow {
  background-color: yellow;
}

.pressed {
  box-shadow: 0 0 20px white;
  background-color: grey;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>Simon</title>
  <link rel="stylesheet" href="styles.css">
  <link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">
</head>

<body>
  <h1 id="level-title">Press A Key to Start</h1>
  <div class="container">
    <div class="row">

      <div type="button" id="green" class="btn green">

      </div>

      <div type="button" id="red" class="btn red">

      </div>
    </div>

    <div class="row">

      <div type="button" id="yellow" class="btn yellow">

      </div>
      <div type="button" id="blue" class="btn blue">

      </div>

    </div>

  </div>

  <script src="index.js" charset="utf-8"></script>
</body>

</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

山川志 2025-01-21 04:02:32

好吧,我什至没有看到您的示例代码来为第一个按钮设置动画。

如果您需要在视觉上“一对一”地发生独立的单独事件,您可以使用 i*1000 作为 setTimeout 第二个参数。

如果没有,我相信这里的代码正在做一些接近您想要实现的事情。定义一个函数,为索引所采用的元素设置所需的道具(本例中为 box-shadow),并为将删除道具并使用下一个索引再次调用第一个函数的函数设置超时:

function animateBtnsSequence( i ){
  var btns = document.querySelectorAll(".btn");
  btns[i].style.boxShadow = '0 0 20px 1px white';

  window.setTimeout(function(){
    btns[i].style.boxShadow = '';
    if( btns[i+1] )
      animateBtnsSequence( i + 1 );
  }, 1000) 

}

function playAllSequence () {
  animateBtnsSequence( 0 );
}

Well, I don't see your sample code to animate even the first button.

If you need independent separate events to happen '1 by 1' visually, you might use a i*1000 as a setTimeout second argument.

If not, here's the code doing something close to what you want to achieve, i believe. Define a function that sets the props you need (box-shadow in this example) for an element taken by index, and sets timeout for a function that will remove the props and call the first function again with the next index:

function animateBtnsSequence( i ){
  var btns = document.querySelectorAll(".btn");
  btns[i].style.boxShadow = '0 0 20px 1px white';

  window.setTimeout(function(){
    btns[i].style.boxShadow = '';
    if( btns[i+1] )
      animateBtnsSequence( i + 1 );
  }, 1000) 

}

function playAllSequence () {
  animateBtnsSequence( 0 );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文