You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

复刻ClickUp居中轮播组件遇阻,求前端技术解决方案

无法复刻ClickUp轮播组件求助

我尝试复刻ClickUp SaaS平台的轮播组件但一直失败,恳请各位帮忙解决!

轮播效果说明:同时显示7个元素,中心元素放大高亮,点击左右元素时,该元素会平滑移动到中心位置,保持元素顺序不变。

具体需求

  • 轮播始终显示7个元素,第4个元素固定处于居中位置
  • 点击中心左侧或右侧的任意元素,该元素需平滑移动至中心,其他元素跟随位移,保持顺序不变
  • 效果需与ClickUp官网的轮播完全一致

已尝试的方案及问题

  • 基于初始与目标索引移动:移动步长固定为7个元素,导致位移不一致,元素无法正确居中
  • 绝对像素值计算移动:使用固定像素值,显示错位,居中元素对齐错误
  • 使用currentOffset计算位置:初始定位错误,元素错位、居中不当
  • CSS像素移动动画:CSS动画与JavaScript计算不同步,引发显示问题
  • 基于点击重新计算:像素移动量计算错误,居中与对齐失效
  • 初始居中与移动计算:初始居中错误,错误元素被居中显示
  • 直接操作translateX:translateX值设置错误,移动与居中不一致

当前代码

HTML

<div class="carousel-wrapper">
  <div class="fade-left"></div>
  <div class="carousel-container">
    <div class="carousel">
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-image"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-subtitles" style="--fa-primary-color: #000;"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-link"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-file-code"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-file-pen"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-wand-magic-sparkles"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-circle-question"></i></div>
      <!-- Dupliquer les éléments pour créer un effet continu -->
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-image"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-subtitles" style="--fa-primary-color: #000;"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-link"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-file-code"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-file-pen"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-wand-magic-sparkles"></i></div>
      <div class="carousel-item"><i class="fa-duotone fa-solid fa-circle-question"></i></div>
    </div>
  </div>
  <div class="fade-right"></div>
</div>

CSS

body {
  font-family: Arial, sans-serif;
  background-color: #f0f0f5;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
}

.carousel-wrapper {
  position: relative;
  width: 70%;
  margin: 0 auto;
  display: flex;
  align-items: center;
}

.carousel-container {
  overflow: hidden;
  width: 100%;
  display: flex;
  justify-content: center;
  position: relative;
  padding-left: 100px;
  padding-right: 100px;
}

.carousel {
  display: flex;
  transition: transform 0.5s ease-in-out;
  position: relative;
}

.carousel-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  margin: 0 30px;
  padding: 20px;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  opacity: 0.6;
  transition: opacity 0.3s ease, transform 0.3s ease-in-out;
  cursor: pointer;
  width: 150px;
}

.carousel-item:hover {
  transform: translateY(-5px);
}

.carousel-item.active {
  opacity: 1;
  transform: scale(1.1);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);
}

.fade-left,
.fade-right {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100px;
  pointer-events: none;
}

.fade-left {
  left: 0;
  background: linear-gradient(to right, rgba(240, 240, 245, 1), rgba(240, 240, 245, 0));
}

.fade-right {
  right: 0;
  background: linear-gradient(to left, rgba(240, 240, 245, 1), rgba(240, 240, 245, 0));
}

.fa-duotone {
  font-size: 50px;
  color: #333;
}

JavaScript

const carousel = document.querySelector('.carousel');
const items = document.querySelectorAll('.carousel-item');
const visibleItems = 7; // Le nombre d'éléments visibles
let currentIndex = Math.floor(items.length / 3); // Index de l'élément central initial

function updateCarousel(newIndex) {
  const middleIndex = Math.floor(visibleItems / 2);
  const offset = newIndex - currentIndex;

  if (newIndex < 0 || newIndex >= items.length) return;

  const itemWidth = items[0].offsetWidth + 60;

  // Déplacer le carrousel pour centrer le nouvel élément cliqué
  carousel.style.transform = `translateX(${-(newIndex - middleIndex) * itemWidth}px)`;

  // Mettre à jour la classe active
  items[currentIndex].classList.remove('active');
  items[newIndex].classList.add('active');

  currentIndex = newIndex; // Mettre à jour l'index courant
}

// Ajouter l'événement de clic à chaque élément du carrousel
items.forEach((item, index) => {
  item.addEventListener('click', () => {
    updateCarousel(index);
  });
});

// Initialiser la position du carrousel
items[currentIndex].classList.add('active');
carousel.style.transform = `translateX(${-(currentIndex - Math.floor(visibleItems / 2)) * (items[0].offsetWidth + 60)}px)`;

内容的提问来源于stack exchange,提问作者bobi bob boby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:39:53