我需要有关此 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>
我有一个容器,里面有 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>