如何实现带缩放淡出效果的左右滑动背景轮播

风之吻 网站开发 98

  要复现 soto.shinfuji.co.jp 那种极具沉浸感的背景轮播——即当前图从满屏略缩放+淡入,上一张图向左平滑滑出并同步缩小淡出——关键不在于更换 Slider 库,而在于精准控制 transform、scale、opacity 的组合动画时序。Slick Slider 本身完全支持该效果,但需深度定制 beforeChange 和 afterChange 回调 + 自定义 CSS 过渡类,而非仅靠 cssEase。

如何实现带缩放淡出效果的左右滑动背景轮播-第1张图片-风享汇

  以下是一个轻量、高性能、无额外依赖的实现方案(兼容现代浏览器):

  ✅ 核心思路

  • 使用 position: absolute 叠加多张背景图(推荐 3 张:prev / current / next)

  • 每张图默认 transform: scale(1.05)(轻微放大以预留缩放空间),opacity: 1

  • 切换时:

   当前图 → 向左位移 + scale(1) + opacity: 1

   下一张图 → 从右侧进入(translateX(100vw))→ scale(1.05) → opacity: 0 → 过渡为 translateX(0), scale(1), opacity: 1

   上一张图 → 向左移出 + scale(0.95) + opacity: 0

  示例代码(纯 CSS + 原生 JS)

<!-- HTML -->
<div class="bg-slider" id="bgSlider">
  <div class="slide active" style="background-image: url('img1.jpg');"></div>
  <div class="slide" style="background-image: url('img2.jpg');"></div>
  <div class="slide" style="background-image: url('img3.jpg');"></div>
</div>
/* CSS */
.bg-slider {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

.slide {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transform: translateX(100vw) scale(1.05);
  transition: transform 1.2s cubic-bezier(0.6, -0.28, 0.735, 0.045),
              opacity 1.2s ease-out,
              scale 1.2s cubic-bezier(0.6, -0.28, 0.735, 0.045);
}

.slide.active {
  opacity: 1;
  transform: translateX(0) scale(1);
}

/* 可选:添加 subtle parallax on scroll */
.slide::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  background: inherit;
  background-size: cover;
  z-index: -1;
  transform: scale(1.1); /* subtle zoom layer */
}
// JS 控制逻辑(自动轮播 + 手动切换)
const slider = document.getElementById('bgSlider');
const slides = Array.from(slider.querySelectorAll('.slide'));
let currentIndex = 0;
let isTransitioning = false;

function goToSlide(index) {
  if (isTransitioning || index === currentIndex) return;
  isTransitioning = true;

  // 移除 active 类
  slides.forEach(s => s.classList.remove('active'));

  // 设置新 slide 为 active
  slides[index].classList.add('active');

  // 重置其他 slide 初始状态(右侧待入场)
  slides.forEach((s, i) => {
    if (i !== index) {
      s.style.transform = 'translateX(100vw) scale(1.05)';
      s.style.opacity = '0';
    }
  });

  // 触发重排,确保 transition 生效
  void slider.offsetWidth;

  // 恢复状态
  setTimeout(() => {
    isTransitioning = false;
  }, 1200);
}

// 自动轮播
setInterval(() => {
  currentIndex = (currentIndex + 1) % slides.length;
  goToSlide(currentIndex);
}, 5000);

// 手动导航示例(可扩展为按钮/键盘)
document.addEventListener('keydown', e => {
  if (e.key === 'ArrowRight') {
    currentIndex = (currentIndex + 1) % slides.length;
    goToSlide(currentIndex);
  } else if (e.key === 'ArrowLeft') {
    currentIndex = (currentIndex - 1 + slides.length) % slides.length;
    goToSlide(currentIndex);
  }
}); 

  ⚠️ 注意事项

  • 性能优先:所有动画属性均基于 transform 和 opacity,确保 GPU 加速;

  • 图片优化:使用 object-fit: cover 或 background-size: cover 并配合 srcset 响应式加载;

  • 无障碍友好:添加 aria-live="polite" 和暂停轮播按钮(prefers-reduced-motion 检测);

  • Slick 替代方案? 若坚持用 Slick,需禁用默认动画(fade: false, cssEase: 'none'),改用 beforeChange 手动添加 class 控制缩放/位移,复杂度反而更高;

  • 移动端适配:建议禁用 touchMove 干扰,或监听 touchstart/touchend 实现手势滑动。

总结:真正流畅的“缩放+滑动”背景轮播,本质是多层 DOM + 精确时序的 CSS 过渡,而非库功能堆砌。上述方案体积

标签: html css javascript

上一篇javascript如何实现文件上传?进度监控怎样完成?

下一篇当前分类已是最新一篇

发布评论 0条评论)

还木有评论哦,快来抢沙发吧~