如何修复这个“轮盘赌”功能?

问题描述 投票:0回答:1

我需要有关此 javascript 函数的帮助,但我无法正常工作。我不得不提一下,我不是开发人员,也不是试图成为开发人员,我只是想自动化一个流程,并决定让 ChatGPT 提供帮助。我有非常基本的 HTML 和 CSS 知识,还有一点点 Javascript,所以我想我也许能够通过 AI 实现这一目标,但我陷入了困境。

基本上,我有一个包含 5 个元素的容器。我正在尝试制作滚动效果,一旦元素开始通过左侧离开容器,它就应该通过右侧滑回到视图中,从而创建这种平滑的连续动画。

现在动画正常开始,但元素没有按照我的需要返回视图。我的意思是他们确实这样做,但他们做得很差,没有顺序,不尊重彼此之间的距离,而且它们并没有真正顺利滑入,它们只是沿着容器的宽度随机弹出。知道我应该如何处理它吗?

const container = document.querySelector('.container');
const elements = document.querySelectorAll('.element');
const rollButton = document.getElementById('rollButton');
let animationInterval = null;

// Set initial positions of elements
elements.forEach(element => {
  element.style.transform = `translateX(0%)`;
  element.direction = -1; // -1 for moving left initially
});

// Function to start or stop the animation when the button is clicked
rollButton.addEventListener('click', () => {
  if (animationInterval === null) {
    // Start animation
    console.log('animation started');
    container.classList.add('rolling');
    const animationDuration = 10000; // Adjust as needed
    const frameRate = 60; // Frames per second
    const distancePerFrame = (container.offsetWidth / animationDuration) * (1000 / frameRate);
    animationInterval = setInterval(() => rollAnimation(distancePerFrame), 1000 / frameRate);
  }
});

// Function to move elements from right to left
function rollAnimation(distancePerFrame) {
  let allElementsLeftContainer = true; // Flag to check if all elements have left the container

  elements.forEach(element => {
    const rect = element.getBoundingClientRect();
    const x = rect.left;
    const y = rect.top;

    // Print the coordinates of each element within the container
    console.log(`Element ${element.id}: x = ${x}, y = ${y}`);

    // Move element based on its direction
    const transformValue = `translateX(${parseFloat(element.style.transform.replace('translateX(', '').replace(')', '')) + distancePerFrame * element.direction}%)`;
    element.style.transform = transformValue;

    if (element.direction === -1 && rect.right < 0) {
      // If element exits through the left side, re-enter from the right side
      const offset = (container.offsetWidth + rect.right) / container.offsetWidth * 100;
      element.style.transform = `translateX(${100 + offset}%)`;
    } else if (element.direction === 1 && rect.left > container.offsetWidth) {
      // If element exits through the right side, re-enter from the left side
      const offset = (rect.left - container.offsetWidth) / container.offsetWidth * 100;
      element.style.transform = `translateX(-${offset}%)`;
    }

    if (rect.left + rect.width > 0) {
      // If any element is still inside the container, set flag to false
      allElementsLeftContainer = false;
    }
  });

  // Check if all elements have left the container
  if (allElementsLeftContainer) {
    // Stop animation
    clearInterval(animationInterval);
    animationInterval = null; // Reset animation interval
    console.log('Animation stopped');
  }
}
.container {
  display: flex;
  justify-content: center;
  /* Center the elements horizontally */
  align-items: center;
  /* Center the elements vertically */
  position: relative;
  width: 100%;
  overflow: hidden;
  /* Hide elements outside the container */
  padding: 0;
  /* Remove padding */
  margin: 0;
  /* Remove margin */
}

.line {
  position: fixed;
  /* Fixed position */
  top: 27%;
  /* Position at the top of the viewport */
  left: 50%;
  /* Position in the middle horizontally */
  width: 2px;
  /* Thickness of the line */
  height: 400px;
  /* Height spanning the entire viewport */
  background-color: black;
  z-index: 1;
  /* Ensure it's above other content */
  transform: translateX(-50%);
  /* Center the line horizontally */
}

.element {
  width: 200px;
  height: 300px;
  margin-right: 40px;
  /* Small space between elements */
  background-color: #E2E8C0;
  /* Background color */
  animation: rollAnimation 10s linear infinite;
}

.element:last-child {
  margin-right: 0;
  /* No margin for the last element */
}

.element img {
  display: block;
  /* Ensure images don't have extra space below */
}

.container.rolling .element {
  animation-play-state: running;
}

.container:not(.rolling) .element {
  animation-play-state: paused;
  transform: translateX(0%);
  /* Reset the position when animation is paused */
}

.element.new {
  animation: rollInFromRight 10s linear;
  /* Adjust duration and easing as needed */
}


/* BUTTON */

#rollButton {
  position: fixed;
  bottom: 20px;
  /* Adjust as needed */
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 20px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

#rollButton:hover {
  background-color: #45a049;
}
<div class="line"></div>

<div class="container">
  <div class="element" id="image1">
    <img src="placeholder1.jpg" alt="Image 1">
  </div>
  <div class="element" id="image2">
    <img src="placeholder2.jpg" alt="Image 2">
  </div>
  <div class="element" id="image3">
    <img src="placeholder3.jpg" alt="Image 3">
  </div>
  <div class="element" id="image4">
    <img src="placeholder4.jpg" alt="Image 4">
  </div>
  <div class="element" id="image5">
    <img src="placeholder5.jpg" alt="Image 5">
  </div>
</div>


<button id="rollButton">Roll</button>

javascript animation
1个回答
0
投票

我有一个容器,里面有 5 个元素。我正在尝试做一个 当元素开始离开容器时滚动效果 通过左侧,它应该通过右侧滑回到视图中 侧面,创建这个流畅的连续动画。

有很多不同的方法可以实现这种效果。

一种方法(如下所示)是进行初始设置,将五个元素的系列加倍,然后在滚动期间继续添加到该系列。


工作示例:

const container = document.querySelector('.container');
const containerBorderLeft = container.getBoundingClientRect().left;
const innerContainerReset = container.innerHTML;
const toggleAnimationButton = document.querySelector('.toggleAnimationButton');
let innerContainer = document.querySelector('.innerContainer');
let circles = document.querySelectorAll('.circle');

const toggleAnimation = () => {

  let i = 0;
  innerContainer.classList.toggle('scrollLeft');
  
  if (!innerContainer.classList.contains('scrollLeft')) {
    container.innerHTML = innerContainerReset;
    innerContainer = document.querySelector('.innerContainer');
    circles = document.querySelectorAll('.circle');
  }  
 
  else {
    setInterval(() => {
      if (circles[i].getBoundingClientRect().right < containerBorderLeft) {
        const newCircle = circles[i].cloneNode();
        innerContainer.appendChild(newCircle);
        circles = document.querySelectorAll('.circle');
        i++;
        innerContainer.style.setProperty('transform', `translateX(calc((10 + ${i}) * -140px))`);
      }
    }, 200);
  }
}

toggleAnimationButton.addEventListener('click', toggleAnimation);
body {
 margin: 24px;
}

.container {
  display: block;
  width: 100%;
  height: 180px;
  margin: 12px;
  background-color: rgb(0, 0, 63);
  overflow: hidden;
}

.innerContainer {
  width: max-content;
  height: 140px;
  transform: translateX(0);
  transition: transform 10s linear;
}

.circle {
  display: inline-block;
  width: 100px;
  height: 100px;
  margin: 40px 20px;
  border-radius: 50%;
}

.circle.red {
  background-color: rgb(255, 0, 0);
}

.circle.orange {
  background-color: rgb(255, 127, 0);
}

.circle.yellow {
  background-color: rgb(255, 255, 0);
}

.circle.green {
  background-color: rgb(0, 191, 0);
}

.circle.blue {
  background-color: rgb(0, 127, 255);
}

.innerContainer.scrollLeft {
  transform: translateX(calc(10 * -140px));
}

.toggleAnimationButton {
  display: block;
  width: 160px;
  height: 24px;
  margin: 0 auto;
  cursor: pointer;
}
<div class="container">
  <div class="innerContainer">
    <div class="circle red"></div>
    <div class="circle orange"></div>
    <div class="circle yellow"></div>
    <div class="circle green"></div>
    <div class="circle blue"></div>
    <div class="circle red"></div>
    <div class="circle orange"></div>
    <div class="circle yellow"></div>
    <div class="circle green"></div>
    <div class="circle blue"></div>
  </div>  
</div>


<button class="toggleAnimationButton">Toggle Animation</button>

© www.soinside.com 2019 - 2024. All rights reserved.