轮播图-2023_05_13

题目:创建一个具有创意交互的 3D 轮播图组件

描述: 请使用 HTML、CSS 和 JavaScript 实现一个具有创意交互的 3D 轮播图组件。要求如下:

  1. 轮播图组件包含至少 5 张图片,图片之间以 3D 效果排列。
  2. 当用户点击图片时,被点击的图片应以动画效果移到中心位置,并成为当前活动项。
  3. 轮播图组件应支持自动播放功能,每隔 3 秒钟自动切换到下一张图片。当用户与轮播图进行交互(如点击)时,自动播放功能暂停;交互结束后,恢复自动播放。
  4. 轮播图组件应具备前进和后退按钮,分别用于切换到上一张和下一张图片。
  5. 实现一个简单的图片指示器,显示当前活动图片的索引。
  6. 轮播图组件应当具有良好的浏览器兼容性。

在完成这道题目时,请重点关注以下知识点:

  1. CSS 3D 变换和过渡效果的应用。
  2. JavaScript 事件处理和 DOM 操作。
  3. 实现自动播放功能及其暂停和恢复机制。
  4. 良好的代码结构和组件化设计。

解答这道题目需要对 CSS 3D 变换、过渡效果以及 JavaScript 事件处理和 DOM 操作有深入的了解。同时,需要有创意地设计轮播图的交互效果和表现形式,使其具有新意且出彩。最后,考虑到浏览器兼容性问题,需要了解不同浏览器中 CSS 和 JavaScript 特性的差异。

答案

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="carousel.css">
  <title>3D Carousel</title>
</head>
<body>
  <div id="carousel-container" class="carousel-container">
    <img src="img1.jpg" class="carousel-img">
    <img src="img2.jpg" class="carousel-img">
    <img src="img3.jpg" class="carousel-img">
    <img src="img4.jpg" class="carousel-img">
    <img src="img5.jpg" class="carousel-img">
    <button id="prev-button" class="carousel-button">Prev</button>
    <button id="next-button" class="carousel-button">Next</button>
  </div>
  <!--JS轮播图文件的名字-->
  <script src="carousel.js"></script>
</body>
</html>

CSS代码

/* 基本样式 */
.carousel-container {
    position: relative;
    width: 800px;
    height: 400px;
    perspective: 1000px;
    overflow: hidden;
    margin: 0 auto;
}
​
.carousel-img {
    position: absolute;
    width: 400px;
    height: 200px;
    object-fit: cover;
    opacity: 0;
    transition: all 1s cubic-bezier(0.5, 0, 0.5, 1); /* 更新过渡效果 */
    transform: translateZ(-200px) rotateY(45deg); /* 添加 3D 旋转效果 */
    left: 50%; /* 添加左偏移 */
    top: 50%; /* 添加上偏移 */
    transform-origin: center center; /* 变换原点设置为中心 */
    pointer-events: none;
    margin-left: -200px; /* 负宽度的一半 */
    margin-top: -100px; /* 负高度的一半 */
    z-index: 1; /* 设置默认的层次 */
}
​
.carousel-button {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    font-size: 2rem;
    background-color: rgba(204, 204, 204, 0.7);
    border: none;
    padding: 10px 20px;
    cursor: pointer;
    opacity: 0.6;
}
​
#prev-button {
    left: 2%;
}
​
#next-button {
    right: 2%;
}
​
/* 轮播图状态样式 */
.carousel-img.active {
    opacity: 1;
    transform: translateZ(180px) scale(1) rotateY(0deg); /* 添加 3D 旋转效果 */
    pointer-events: auto;
    z-index: 3; /* 设置最高层次 */
}
​
.carousel-img.prev,
.carousel-img.next {
    z-index: 2; /* 设置较高层次 */
}
​
.carousel-img.prev {
    opacity: 0.4;
    transform: translateX(-50%) translateZ(0) scale(0.8) rotateY(-30deg); /* 添加 3D 旋转效果 */
    pointer-events: auto;
}
​
.carousel-img.next {
    opacity: 0.6;
    transform: translateX(50%) translateZ(0) scale(0.8) rotateY(30deg); /* 添加 3D 旋转效果 */
    pointer-events: auto;
}
​

JS代码

class Carousel {
 constructor(containerSelector) {
   // 获取轮播图容器
   this.container = document.querySelector(containerSelector);
   // 获取所有轮播图片元素
   this.images = this.container.querySelectorAll('.carousel-img');
   // 获取向前翻页按钮
   this.prevButton = this.container.querySelector('#prev-button');
   // 获取向后翻页按钮
   this.nextButton = this.container.querySelector('#next-button');
​
   // 当前展示图片的索引
   this.activeIndex = 0;
   // 动画状态
   this.isAnimating = false;
   // 自动播放定时器
   this.autoPlayTimer = null;
   // 触摸开始时的 X 坐标
   this.lastTouchX = null;
​
   // 初始化组件
   this.init();
}
​
 init() {
   // 更新图片位置
   this.updateImagePositions();
   // 开始自动播放
   this.startAutoPlay();
​
   // 添加向前翻页事件监听
   this.prevButton.addEventListener('click', () => {
     this.prev();
   });
​
   // 添加向后翻页事件监听
   this.nextButton.addEventListener('click', () => {
     this.next();
   });
​
   // 为每张图片添加点击事件监听,设置当前展示图片
   this.images.forEach((img, index) => {
     img.addEventListener('click', () => {
       this.setActiveIndex(index);
     });
   });
​
   // 添加触摸开始事件监听
   this.container.addEventListener('touchstart', (event) => {
     // 暂停自动播放
     this.pauseAutoPlay();
     // 记录触摸开始时的 X 坐标
     this.lastTouchX = event.touches[0].clientX;
   });
​
   // 添加触摸移动事件监听
   this.container.addEventListener('touchmove', (event) => {
     if (this.lastTouchX !== null) {
       // 计算触摸位移
       const deltaX = this.lastTouchX - event.touches[0].clientX;
       // 更新触摸起始点
       this.lastTouchX = event.touches[0].clientX;
       // 根据位移判断是向前翻页还是向后翻页
       if (deltaX > 0) {
         this.next();
       } else {
         this.prev();
       }
     }
   });
​
   // 添加触摸结束事件监听
   this.container.addEventListener('touchend', () => {
     // 恢复自动播放
     this.resumeAutoPlay();
     // 重置触摸起始点
     this.lastTouchX = null;
   });
}
​
 updateImagePositions() {
   const positionMap = {
     0: 'active',
     1: 'next',
     '-1': 'prev',
   };
​
   // 为每张图片设置对应的类名
   this.images.forEach((img, index) => {
     const diff = index - this.activeIndex;
​
     // 使用映射代替 if-else 判断
     img.className = `carousel-img ${positionMap[diff] || ''}`;
   });
}
​
 prev() {
   // 计算向前翻页后的当前展示图片索引
   this.activeIndex = (this.activeIndex - 1 + this.images.length) % this.images.length;
   // 更新图片位置
   this.updateImagePositions();
}
​
 next() {
// 计算向后翻页后的当前展示图片索引
   this.activeIndex = (this.activeIndex + 1) % this.images.length;
// 更新图片位置
   this.updateImagePositions();
}
​
 setActiveIndex(index) {
// 设置当前展示图片的索引
   this.activeIndex = index;
// 更新图片位置
   this.updateImagePositions();
}
​
 startAutoPlay() {
// 开启自动播放定时器
   this.autoPlayTimer = setInterval(() => {
     this.next();
   }, 3000);
}
​
 pauseAutoPlay() {
// 清除自动播放定时器
   clearInterval(this.autoPlayTimer);
}
​
 resumeAutoPlay() {
// 重新开始自动播放
   this.startAutoPlay();
}
}
​
// 初始化 Carousel 组件
document.addEventListener('DOMContentLoaded', () => {
 new Carousel('#carousel-container');
});

轮播图-2023_05_13

原文链接:https://juejin.cn/post/7232645675158437944 作者:2002XiaoYu

(0)
上一篇 2023年5月14日 上午10:05
下一篇 2023年5月14日 上午10:15

相关推荐

发表回复

登录后才能评论