动画以下轮播实施的最低限度步骤是什么?

What could be the bare minimum steps to animate the following carousel implementation?

我正在制作香草 js 轮播。我已经使用 js 以及 html 和 css.

列出了基本的上一个和下一个功能

现在我尝试使用 css-动画(关键帧)来制作左右 slide-in/slide-out 动画,但代码对我来说变得很乱。所以在这里我要问的是,要在这个实现中获得相同的动画效果,需要进行哪些最小的更改?

你会选择纯 JS 还是纯 CSS 还是混合来做同样的事情?

我的目标是用最少的代码获得合适的动画。

(function () {
  let visibleIndex = 0;
  let carousalImages = document.querySelectorAll(".carousal__image");
  let totalImages = [...carousalImages].length;

  function makeNextVisible() {
    visibleIndex++;
    if (visibleIndex > totalImages - 1) {
      visibleIndex = 0;
    }
    resetVisible();
    renderVisible();
  }
  function makePrevVisible() {
    visibleIndex--;
    if (visibleIndex < 0) {
      visibleIndex = totalImages - 1;
    }
    resetVisible();
    renderVisible();
  }

  function resetVisible() {
    for (let index = 0; index < totalImages; index++) {
      carousalImages[index].className = "carousal__image";
    }
  }
  function renderVisible() {
    carousalImages[visibleIndex].className = "carousal__image--visible";
  }

  function renderCarousel({ autoplay = false, autoplayTime = 1000 } = {}) {
    if (autoplay) {
      [...document.querySelectorAll("button")].forEach(
        (btn) => (btn.style.display = "none")
      );
      setInterval(() => {
        makeNextVisible();
      }, autoplayTime);
    } else renderVisible();
  }

  renderCarousel();

  // Add {autoplay:true} as argument to above to autplay the carousel.

  this.makeNextVisible = makeNextVisible;
  this.makePrevVisible = makePrevVisible;
})();
.carousal {
  display: flex;
  align-items: center;
}
.carousal__wrapper {
  width: 500px;
  height: 400px;
}
.carousal__images {
  display: flex;
  overflow: hidden;
  list-style-type: none;
  padding: 0;
}
.carousal__image--visible {
  position: relative;
}
.carousal__image {
  display: none;
}
<div class='carousal'>
  <div class='carousal__left'>
    <button onclick='makePrevVisible()'>Left</button>
  </div>
  <section class='carousal__wrapper'>
    <ul class='carousal__images'>
      <li class='carousal__image'>
        <img src='https://fastly.syfy.com/sites/syfy/files/styles/1200x680/public/2018/03/dragon-ball-super-goku-ultra-instinct-mastered-01.jpg?offset-x=0&offset-y=0' alt='UI Goku' / width='500' height='400'/>
      </li>
      <li class='carousal__image'>
        <img src='https://www.theburnin.com/wp-content/uploads/2019/01/super-broly-3.png' alt='Broly Legendary'  width='500' height='400'/>
      </li>
      <li class='carousal__image'>
        <img src='https://lh3.googleusercontent.com/proxy/xjEVDYoZy8-CTtPZGsQCq2PW7I-1YM5_S5GPrAdlYL2i4SBoZC-zgtg2r3MqH85BubDZuR3AAW4Gp6Ue-B-T2Z1FkKW99SPHwAce5Q_unUpwtm4' alt='Vegeta Base' width='500' height='400'/>
      </li>
      <li class='carousal__image'>
        <img src='https://am21.mediaite.com/tms/cnt/uploads/2018/09/GohanSS2.jpg' alt='Gohan SS2'  width='500' height='400'/>
      </li>
    </ul>
  </section>
  <div class='carousal__right'>
    <button onclick='makeNextVisible()'>Right</button>
  </div>
</div>

根据以下答案和次要附加功能的反馈更新了 codepen = https://codepen.io/lapstjup/pen/RwoRWVe

我觉得这个技巧很简单。 ;)

您不应同时移动一张或两张图片。相反,您应该一次移动所有图像。

让我们从 CSS:

开始
.carousal {
  position: relative;
  display: block;
}

.carousal__wrapper {
  width: 500px;
  height: 400px;
  position: relative;
  display: block;
  overflow: hidden;
  margin: 0;
  padding: 0;
}
.carousal__wrapper,
.carousal__images {
  transform: translate3d(0, 0, 0);
}

.carousal__images {
  position: relative;
  top: 0;
  left: 0;
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.carousal__image {
  float: left;
  height: 100%;
  min-height: 1px;
}

第二步是计算 .carousal__images 的最大宽度。例如,在您的情况下,4 * 500px 等于 2000px。此值必须作为样式属性 style="width: 2000px".

的一部分添加到您的 carousal__images

第三步是计算下一个动画点并使用 transform: translate3d。我们从 0 开始,想要下一张幻灯片,这意味着我们向左滑动。我们也知道一张幻灯片的宽度。所以结果将是 -500px 还必须添加 carousal__images => style="width: 2000px; transform: translate3d(-500px, 0px, 0px);"

的样式属性

就是这样。

Link 到我的 CodePen:Codepen for Basic Carousel with Autoplay

试试这个。首先将所有图像并排堆叠在 div 中,并通过将 divoverflow 属性 设置为 hidden 一次只显示一张图像.接下来,将事件侦听器添加到按钮。单击底部时,包含图像的 div 会在 x 轴上平移 -{size of an image} * {image number}。为了流畅的动画,将 transition: all 0.5s ease-in-out; 添加到 div.

当有人在第一张图片上单击 left arrow 时,幻灯片应显示最后一张图片。因此 counter 设置为 {number of images} - 1 并且图像被平移到左侧 size * counter 像素。

每单击一次右箭头,计数器就会增加 1,并且幻灯片会向左移动。每单击一次左箭头,计数器就会减 1。

Slide.style.transform = "translateX(" + (-size * counter) + "px)"; 这是决定幻灯片翻译多少的条件。

const PreviousButton = document.querySelector(".Previous-Button");
const NextButton = document.querySelector(".Next-Button");
const Images = document.querySelectorAll("img");
const Slide = document.querySelector(".Images");
const size = Slide.clientWidth;
var counter = 0;

// Arrow Click Events
PreviousButton.addEventListener("click", Previous);
NextButton.addEventListener("click", Next);

function Previous() {
  counter--;

  if (counter < 0) {
    counter = Images.length - 1;
  }

  Slide.style.transform = "translateX(" + (-size * counter) + "px)";
}

function Next() {
  counter++;

  if (counter >= Images.length) {
    counter = 0;
  }

  Slide.style.transform = "translateX(" + (-size * counter) + "px)";
}
* {
  margin: 0px;
  padding: 0px;
  box-sizing: border-box;
}

.Container {
  width: 60%;
  margin: 0px auto;
  margin-top: 90px;
  overflow: hidden;
  position: relative;
}

.Container .Images img {
  width: 100%;
}

.Images {
  transition: all 0.5s ease-in-out;
}

.Container .Previous-Button {
  position: absolute;
  background: transparent;
  border: 0px;
  outline: 0px;
  top: 50%;
  left: 20px;
  transform: translateY(-50%);
  filter: invert(80%);
  z-index: 1;
}

.Container .Next-Button {
  position: absolute;
  background: transparent;
  border: 0px;
  outline: 0px;
  top: 50%;
  right: 20px;
  transform: translateY(-50%);
  filter: invert(80%);
  z-index: 1;
}

.Container .Images {
  display: flex;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link href="https://fonts.googleapis.com/css2?family=Cabin&family=Poppins&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
  <title>Carousel</title>
</head>

<body>
  <div class="Container">
    <button class="Previous-Button">
            <svg style = "transform: rotate(180deg);" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M8.122 24l-4.122-4 8-8-8-8 4.122-4 11.878 12z"/></svg>
        </button>
    <button class="Next-Button">
            <svg xmlns="http://www.w3.org/2000/svg" width = "24" height = "24" viewBox = "0 0 24 24"><path d="M8.122 24l-4.122-4 8-8-8-8 4.122-4 11.878 12z"/></svg>
        </button>
    <div class="Images">
      <img src="https://source.unsplash.com/1280x720/?nature">
      <img src="https://source.unsplash.com/1280x720/?water">
      <img src="https://source.unsplash.com/1280x720/?rock">
      <img src="https://source.unsplash.com/1280x720/?abstract">
      <img src="https://source.unsplash.com/1280x720/?nature">
      <img src="https://source.unsplash.com/1280x720/?trees">
      <img src="https://source.unsplash.com/1280x720/?human">
      <img src="https://source.unsplash.com/1280x720/?tech">
    </div>
  </div>
  <script src="main.js"></script>
</body>

</html>