响应式拖拽滑动带缩略图相册

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式拖拽滑动带缩略图相册</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Arial', sans-serif;
            background-color: #f5f5f5;
            padding: 20px;
        }
        
        .gallery-container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: white;
            border-radius: 10px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
        }
        
        h1 {
            text-align: center;
            margin-bottom: 30px;
            color: #333;
        }
        
        .main-slider {
            position: relative;
            width: 100%;
            height: 500px;
            overflow: hidden;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        
        @media (max-width: 768px) {
            .main-slider {
                height: 300px;
            }
        }
        
        .main-slide {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            opacity: 0;
            transition: opacity 0.5s ease;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .main-slide.active {
            opacity: 1;
        }
        
        .main-slide img {
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
            cursor: grab;
            user-select: none;
        }
        
        .main-slide img:active {
            cursor: grabbing;
        }
        
        .thumbnails-container {
            width: 100%;
            overflow-x: auto;
            padding: 10px 0;
            scrollbar-width: none; /* Firefox */
            -ms-overflow-style: none; /* IE and Edge */
        }
        
        .thumbnails-container::-webkit-scrollbar {
            display: none; /* Chrome, Safari, Opera */
        }
        
        .thumbnails {
            display: flex;
            gap: 10px;
            width: max-content;
            padding: 0 10px;
        }
        
        .thumbnail {
            width: 120px;
            height: 80px;
            border-radius: 5px;
            overflow: hidden;
            cursor: pointer;
            transition: transform 0.2s ease, box-shadow 0.2s ease;
            flex-shrink: 0;
            position: relative;
        }
        
        .thumbnail:hover {
            transform: scale(1.05);
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
        }
        
        .thumbnail.active {
            border: 3px solid #3498db;
            transform: scale(1.05);
        }
        
        .thumbnail img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        
        .navigation {
            display: flex;
            justify-content: center;
            margin-top: 20px;
            gap: 15px;
        }
        
        .nav-btn {
            padding: 10px 20px;
            background-color: #3498db;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }
        
        .nav-btn:hover {
            background-color: #2980b9;
        }
        
        .nav-btn:disabled {
            background-color: #95a5a6;
            cursor: not-allowed;
        }
        
        .drag-info {
            text-align: center;
            margin-top: 10px;
            color: #7f8c8d;
            font-size: 14px;
        }
        
        /* 拖拽指示器 */
        .drag-indicator {
            position: absolute;
            top: 10px;
            right: 10px;
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 5px 10px;
            border-radius: 20px;
            font-size: 12px;
            display: none;
        }
    </style>
</head>
<body>
    <div class="gallery-container">
        <h1>响应式拖拽滑动相册</h1>
        
        <div class="main-slider">
            <div class="main-slide active">
                <img src="https://picsum.photos/1200/800?random=1" alt="Image 1" draggable="false">
                <div class="drag-indicator">拖拽查看</div>
            </div>
            <div class="main-slide">
                <img src="https://picsum.photos/1200/800?random=2" alt="Image 2" draggable="false">
                <div class="drag-indicator">拖拽查看</div>
            </div>
            <div class="main-slide">
                <img src="https://picsum.photos/1200/800?random=3" alt="Image 3" draggable="false">
                <div class="drag-indicator">拖拽查看</div>
            </div>
            <div class="main-slide">
                <img src="https://picsum.photos/1200/800?random=4" alt="Image 4" draggable="false">
                <div class="drag-indicator">拖拽查看</div>
            </div>
            <div class="main-slide">
                <img src="https://picsum.photos/1200/800?random=5" alt="Image 5" draggable="false">
                <div class="drag-indicator">拖拽查看</div>
            </div>
            <div class="main-slide">
                <img src="https://picsum.photos/1200/800?random=6" alt="Image 6" draggable="false">
                <div class="drag-indicator">拖拽查看</div>
            </div>
        </div>
        
        <div class="drag-info">您可以拖拽主图片查看完整内容</div>
        
        <div class="thumbnails-container">
            <div class="thumbnails">
                <div class="thumbnail active" data-index="0">
                    <img src="https://picsum.photos/120/80?random=1" alt="Thumbnail 1">
                </div>
                <div class="thumbnail" data-index="1">
                    <img src="https://picsum.photos/120/80?random=2" alt="Thumbnail 2">
                </div>
                <div class="thumbnail" data-index="2">
                    <img src="https://picsum.photos/120/80?random=3" alt="Thumbnail 3">
                </div>
                <div class="thumbnail" data-index="3">
                    <img src="https://picsum.photos/120/80?random=4" alt="Thumbnail 4">
                </div>
                <div class="thumbnail" data-index="4">
                    <img src="https://picsum.photos/120/80?random=5" alt="Thumbnail 5">
                </div>
                <div class="thumbnail" data-index="5">
                    <img src="https://picsum.photos/120/80?random=6" alt="Thumbnail 6">
                </div>
            </div>
        </div>
        
        <div class="navigation">
            <button class="nav-btn prev-btn" disabled>上一张</button>
            <button class="nav-btn next-btn">下一张</button>
        </div>
        

    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const mainSlides = document.querySelectorAll('.main-slide');
            const thumbnails = document.querySelectorAll('.thumbnail');
            const prevBtn = document.querySelector('.prev-btn');
            const nextBtn = document.querySelector('.next-btn');
            const thumbnailsContainer = document.querySelector('.thumbnails-container');
            const dragIndicators = document.querySelectorAll('.drag-indicator');
            
            let currentIndex = 0;
            let isDragging = false;
            let startPosX = 0;
            let currentTranslate = 0;
            let prevTranslate = 0;
            let animationID;
            
            // 初始化相册
            function initGallery() {
                updateButtons();
                setupThumbnailScroll();
                setupDragEvents();
            }
            
            // 更新导航按钮状态
            function updateButtons() {
                prevBtn.disabled = currentIndex === 0;
                nextBtn.disabled = currentIndex === mainSlides.length - 1;
            }
            
            // 设置缩略图滚动位置
            function setupThumbnailScroll() {
                const activeThumb = thumbnails[currentIndex];
                const containerWidth = thumbnailsContainer.offsetWidth;
                const thumbWidth = activeThumb.offsetWidth;
                const thumbLeft = activeThumb.offsetLeft;
                
                // 计算滚动位置,使当前缩略图居中
                const scrollTo = thumbLeft - (containerWidth / 2) + (thumbWidth / 2);
                thumbnailsContainer.scrollTo({
                    left: scrollTo,
                    behavior: 'smooth'
                });
            }
            
            // 设置拖拽事件
            function setupDragEvents() {
                mainSlides.forEach((slide, index) => {
                    const image = slide.querySelector('img');
                    
                    // 触摸事件
                    image.addEventListener('touchstart', touchStart(index));
                    image.addEventListener('touchend', touchEnd);
                    image.addEventListener('touchmove', touchMove);
                    
                    // 鼠标事件
                    image.addEventListener('mousedown', dragStart(index));
                    image.addEventListener('mouseup', dragEnd);
                    image.addEventListener('mouseleave', dragEnd);
                    image.addEventListener('mousemove', dragMove);
                    
                    // 防止拖动时选中文本
                    image.addEventListener('selectstart', (e) => e.preventDefault());
                });
            }
            
            // 切换到指定索引的幻灯片
            function goToSlide(index) {
                if (index < 0 || index >= mainSlides.length) return;
                
                mainSlides[currentIndex].classList.remove('active');
                thumbnails[currentIndex].classList.remove('active');
                
                currentIndex = index;
                
                mainSlides[currentIndex].classList.add('active');
                thumbnails[currentIndex].classList.add('active');
                
                updateButtons();
                setupThumbnailScroll();
            }
            
            // 上一张
            function prevSlide() {
                goToSlide(currentIndex - 1);
            }
            
            // 下一张
            function nextSlide() {
                goToSlide(currentIndex + 1);
            }
            
            // 触摸开始
            function touchStart(index) {
                return function(event) {
                    startPosX = event.touches[0].clientX;
                    currentTranslate = 0;
                    prevTranslate = 0;
                    isDragging = true;
                    animationID = requestAnimationFrame(animation);
                    showDragIndicator(index);
                };
            }
            
            // 触摸移动
            function touchMove(event) {
                if (!isDragging) return;
                const currentPosition = event.touches[0].clientX;
                currentTranslate = currentPosition - startPosX;
            }
            
            // 触摸结束
            function touchEnd() {
                if (!isDragging) return;
                isDragging = false;
                cancelAnimationFrame(animationID);
                hideDragIndicator();
                
                // 根据拖动距离决定是否切换幻灯片
                if (Math.abs(currentTranslate) > 50) {
                    if (currentTranslate > 0) {
                        prevSlide();
                    } else {
                        nextSlide();
                    }
                }
            }
            
            // 拖拽开始
            function dragStart(index) {
                return function(event) {
                    startPosX = event.clientX;
                    currentTranslate = 0;
                    prevTranslate = 0;
                    isDragging = true;
                    animationID = requestAnimationFrame(animation);
                    showDragIndicator(index);
                };
            }
            
            // 拖拽移动
            function dragMove(event) {
                if (!isDragging) return;
                const currentPosition = event.clientX;
                currentTranslate = currentPosition - startPosX;
            }
            
            // 拖拽结束
            function dragEnd() {
                if (!isDragging) return;
                isDragging = false;
                cancelAnimationFrame(animationID);
                hideDragIndicator();
                
                // 根据拖动距离决定是否切换幻灯片
                if (Math.abs(currentTranslate) > 50) {
                    if (currentTranslate > 0) {
                        prevSlide();
                    } else {
                        nextSlide();
                    }
                }
            }
            
            // 动画帧
            function animation() {
                if (!isDragging) return;
                
                const activeSlide = mainSlides[currentIndex];
                const image = activeSlide.querySelector('img');
                
                // 应用平移效果
                image.style.transform = `translateX(${currentTranslate}px)`;
                
                animationID = requestAnimationFrame(animation);
            }
            
            // 显示拖拽指示器
            function showDragIndicator(index) {
                dragIndicators[index].style.display = 'block';
            }
            
            // 隐藏拖拽指示器
            function hideDragIndicator() {
                dragIndicators.forEach(indicator => {
                    indicator.style.display = 'none';
                });
                
                // 重置图片位置
                mainSlides.forEach(slide => {
                    const image = slide.querySelector('img');
                    image.style.transform = 'translateX(0)';
                });
            }
            
            // 事件监听
            prevBtn.addEventListener('click', prevSlide);
            nextBtn.addEventListener('click', nextSlide);
            
            thumbnails.forEach(thumbnail => {
                thumbnail.addEventListener('click', function() {
                    const index = parseInt(this.getAttribute('data-index'));
                    goToSlide(index);
                });
            });
            
            // 键盘导航
            document.addEventListener('keydown', function(e) {
                if (e.key === 'ArrowLeft') {
                    prevSlide();
                } else if (e.key === 'ArrowRight') {
                    nextSlide();
                }
            });
            
            // 初始化相册
            initGallery();
        });
    </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值