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

求助:实现自动滚动Slider视口居中图片放大效果(CSS/JS)

实现自动滚动Slider的中心元素放大效果

我有一个自动滚动的Slider,希望当img元素处于视口中心时放大,离开中心后恢复原尺寸;下一个元素到达视口中心时同样放大,离开后恢复,循环往复。以下是我的HTML和CSS代码:

原HTML代码:

</head>
<body>
<section class="slider">
      <ul>
        <li>
          <img src="https://placehold.co/600x400" alt="" class="elementSlide">
          <div class="center">Hi<br>Hello World</div>
        </li>
        <li>
          <img src="https://placehold.co/600x400" alt="" class="elementSlide">
          <div class="center">Hi<br>Hello World</div>
        </li>
        <li>
          <img src="https://placehold.co/600x400" alt="" class="elementSlide">
          <div class="center">Hi<br>Hello World</div>
        </li>
        <li>
          <img src="https://placehold.co/600x400" alt="" class="elementSlide">
          <div class="center">Hi<br>Hello World</div>
        </li>

        <li>
          <img src="https://placehold.co/600x400" alt="" class="elementSlide">
          <div class="center">Hi<br>Hello World</div>
        </li>
        <li>
          <img src="https://placehold.co/600x400" alt="" class="elementSlide">
          <div class="center">Hi<br>Hello World</div>
        </li>
        <li>
          <img src="https://placehold.co/600x400" alt="" class="elementSlide">
          <div class="center">Hi<br>Hello World</div>
        </li>
        <li>
          <img src="https://placehold.co/600x400" alt="" class="elementSlide">
          <div class="center">Hi<br>Hello World</div>
        </li>
      </ul>
    </section>
</body>

原CSS代码:

.slider {
  overflow: hidden;
}

.slider ul {
  display: flex;
  justify-content: center;
  align-items: center;
  width: max-content;
  animation: runSlider 20s linear infinite; 
}

.slider img {
  width: 40vw;
  height: 25vw;
  border-radius: 5vw;
}

.slider li {
  display: flex;
  justify-content: start;
  align-items: center;
  margin-right: 5vw;
  color: white;
  position: relative;
  height: 40vw;
}

.center {
  position: absolute;
  top: 50%;
  right: 10%;
  transform: translate(0%, -50%);
  font-size: 4vw;
  text-align: end;
  text-shadow: 1px 1px black;
}

@keyframes runSlider {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(calc(-45vw * 4));
  }
}

方案一:纯CSS实现(基于动画同步)

利用CSS动画同步特性,让缩放动画与滚动动画时长一致,精准控制每个图片在到达视口中心时放大。

修改后的CSS代码:

.slider {
  overflow: hidden;
  position: relative;
  /* 可选:添加中心参考线,方便调试 */
  /* &::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 2px;
    height: 100%;
    background: red;
  } */
}

.slider ul {
  display: flex;
  justify-content: center;
  align-items: center;
  width: max-content;
  animation: runSlider 20s linear infinite; 
}

.slider img {
  width: 40vw;
  height: 25vw;
  border-radius: 5vw;
  transition: transform 0.3s ease; /* 平滑过渡缩放效果 */
  animation: zoom 20s linear infinite; /* 同步滚动时长的缩放动画 */
}

.slider li {
  display: flex;
  justify-content: start;
  align-items: center;
  margin-right: 5vw;
  color: white;
  position: relative;
  height: 40vw;
}

.center {
  position: absolute;
  top: 50%;
  right: 10%;
  transform: translate(0%, -50%);
  font-size: 4vw;
  text-align: end;
  text-shadow: 1px 1px black;
}

@keyframes runSlider {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(calc(-45vw * 4));
  }
}

/* 缩放动画:与滚动动画时长一致,关键帧对应元素到达中心的时间点 */
@keyframes zoom {
  /* 8个元素,20s滚动周期,每个元素间隔2.5s到达中心 */
  0%, 10.4%, 35.4%, 60.4%, 85.4%, 100% {
    transform: scale(1); /* 非中心状态 */
  }
  12.5%, 37.5%, 62.5%, 87.5% {
    transform: scale(1.2); /* 中心状态,放大1.2倍 */
  }
}

/* 为每个图片设置延迟,匹配各自到达中心的时间 */
.slider li:nth-child(1) img { animation-delay: 0s; }
.slider li:nth-child(2) img { animation-delay: -2.5s; }
.slider li:nth-child(3) img { animation-delay: -5s; }
.slider li:nth-child(4) img { animation-delay: -7.5s; }
.slider li:nth-child(5) img { animation-delay: -10s; }
.slider li:nth-child(6) img { animation-delay: -12.5s; }
.slider li:nth-child(7) img { animation-delay: -15s; }
.slider li:nth-child(8) img { animation-delay: -17.5s; }

注意事项:

  • 关键帧百分比需要根据元素数量和滚动时长调整,确保缩放时机与元素到达中心的时间完全同步。
  • 若修改滚动时长或元素数量,需重新计算间隔时间和关键帧百分比。

方案二:JavaScript实现(动态检测)

如果需要适配窗口大小变化、动态调整元素数量等场景,用JS实时检测元素位置更灵活。

修改后的CSS(新增放大类):

.slider {
  overflow: hidden;
}

.slider ul {
  display: flex;
  justify-content: center;
  align-items: center;
  width: max-content;
  animation: runSlider 20s linear infinite; 
}

.slider img {
  width: 40vw;
  height: 25vw;
  border-radius: 5vw;
  transition: transform 0.3s ease; /* 平滑过渡 */
}

/* 放大样式类 */
.slider img.zoom {
  transform: scale(1.2);
}

.slider li {
  display: flex;
  justify-content: start;
  align-items: center;
  margin-right: 5vw;
  color: white;
  position: relative;
  height: 40vw;
}

.center {
  position: absolute;
  top: 50%;
  right: 10%;
  transform: translate(0%, -50%);
  font-size: 4vw;
  text-align: end;
  text-shadow: 1px 1px black;
}

@keyframes runSlider {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(calc(-45vw * 4));
  }
}

JavaScript代码:

const sliderImgs = document.querySelectorAll('.elementSlide');
let viewportCenterX = window.innerWidth / 2;

// 检测元素是否处于视口中心范围
function checkCenterPosition() {
  sliderImgs.forEach(img => {
    const rect = img.getBoundingClientRect();
    const imgCenterX = rect.left + rect.width / 2;
    // 设定50px的阈值,元素中心进入该范围时放大
    const isInCenter = Math.abs(imgCenterX - viewportCenterX) < 50;
    img.classList.toggle('zoom', isInCenter);
  });
}

// 初始检测
checkCenterPosition();

// 持续检测动画状态
function animateCheck() {
  checkCenterPosition();
  requestAnimationFrame(animateCheck);
}
animateCheck();

// 窗口大小变化时更新视口中心
window.addEventListener('resize', () => {
  viewportCenterX = window.innerWidth / 2;
});

优势:

  • 无需手动计算关键帧,自动适配元素位置变化。
  • 支持窗口大小动态调整,兼容性更强。

内容的提问来源于stack exchange,提问作者Haitham

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:47:00