• 响应式设计:在手机、平板和电脑上都能良好显示。
  • 核心功能
    • 缩略图导航:点击缩略图可以快速切换主图。
    • 左右箭头:浏览上一张/下一张照片。
    • 图片计数器:显示当前是第几张图片(3 / 8)。
    • 平滑过渡:图片切换时有淡入淡出的动画效果。
  • 高级特效
    • 自动播放/暂停:鼠标悬停在相册上时暂停自动播放。
    • 键盘控制:使用键盘左右箭头键也可以切换图片。
    • 放大镜特效:鼠标悬停在主图上时,可以查看图片的放大细节。

最终效果预览


第一步:HTML 结构

我们需要创建相册的基本HTML结构,我们将使用一个主容器来包裹所有元素,包括一张主图、导航箭头、计数器和缩略图列表。

css网页动态相册js特效代码
(图片来源网络,侵删)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">CSS & JS 动态相册</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="gallery-container">
        <!-- 主图区域 -->
        <div class="main-image-container">
            <img id="mainImage" src="https://picsum.photos/seed/img1/800/500.jpg" alt="主图">
            <!-- 放大镜效果层 -->
            <div class="magnifier-glass"></div>
            <!-- 左右箭头 -->
            <button class="nav-btn prev-btn">&#10094;</button>
            <button class="nav-btn next-btn">&#10095;</button>
            <!-- 图片计数器 -->
            <div class="image-counter">
                <span id="currentIndex">1</span> / <span id="totalImages">8</span>
            </div>
        </div>
        <!-- 缩略图导航区域 -->
        <div class="thumbnail-list">
            <!-- 缩略图将通过JS动态生成 -->
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

代码说明

  • gallery-container: 整个相册的包裹容器。
  • main-image-container: 主图的显示区域,包含所有相关控件。
  • mainImage: 用于显示当前选中的大图。
  • magnifier-glass: 用于实现放大镜效果的可视层。
  • nav-btn: 左右导航按钮。
  • image-counter: 显示图片序号的计数器。
  • thumbnail-list: 缩略图的列表容器,初始为空,将由JS填充。

第二步:CSS 样式

我们使用CSS来美化相册,并添加过渡动画和放大镜特效的样式。

/* style.css */
body {
    font-family: 'Arial', sans-serif;
    background-color: #f0f2f5;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}
.gallery-container {
    max-width: 900px;
    width: 100%;
    background-color: #fff;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
    border-radius: 12px;
    overflow: hidden;
}
/* 主图区域样式 */
.main-image-container {
    position: relative;
    width: 100%;
    height: 500px;
    overflow: hidden;
}
#mainImage {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: opacity 0.5s ease-in-out; /* 图片切换的淡入淡出效果 */
}
/* 导航按钮样式 */
.nav-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background-color: rgba(0, 0, 0, 0.5);
    color: white;
    border: none;
    font-size: 2rem;
    padding: 15px 20px;
    cursor: pointer;
    border-radius: 50%;
    transition: background-color 0.3s ease, transform 0.2s ease;
    z-index: 10;
}
.nav-btn:hover {
    background-color: rgba(0, 0, 0, 0.8);
}
.prev-btn {
    left: 20px;
}
.next-btn {
    right: 20px;
}
/* 图片计数器样式 */
.image-counter {
    position: absolute;
    bottom: 20px;
    right: 20px;
    background-color: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 8px 15px;
    border-radius: 20px;
    font-size: 0.9rem;
    z-index: 10;
}
/* 缩略图列表样式 */
.thumbnail-list {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
    gap: 15px;
    flex-wrap: wrap; /* 在小屏幕上自动换行 */
    background-color: #fafafa;
}
.thumbnail {
    width: 80px;
    height: 60px;
    object-fit: cover;
    border-radius: 8px;
    cursor: pointer;
    opacity: 0.6;
    transition: opacity 0.3s ease, transform 0.2s ease, border 0.3s ease;
    border: 2px solid transparent;
}
.thumbnail:hover {
    opacity: 0.8;
    transform: scale(1.05);
}
.thumbnail.active {
    opacity: 1;
    border-color: #007bff;
}
/* --- 放大镜特效样式 --- */
.magnifier-glass {
    position: absolute;
    border: 3px solid #fff;
    border-radius: 50%;
    cursor: none;
    width: 150px;
    height: 150px;
    display: none; /* 默认隐藏 */
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.4);
    pointer-events: none; /* 确保鼠标事件能穿透到下面的图片 */
}
/* 响应式设计 */
@media (max-width: 768px) {
    .main-image-container {
        height: 350px;
    }
    .thumbnail {
        width: 60px;
        height: 45px;
    }
    .nav-btn {
        font-size: 1.5rem;
        padding: 10px 15px;
    }
}

代码说明

  • #mainImagetransition: opacity: 这是实现图片淡入淡出的关键,当src属性改变时,浏览器会先加载新图片,加载完成后,通过改变opacity来实现平滑过渡。
  • .thumbnailactive: 用于高亮显示当前选中的缩略图。
  • .magnifier-glass: 这是放大镜的“镜片”,它被设置为绝对定位,默认隐藏,pointer-events: none 确保它不会干扰鼠标与主图的交互。
  • 响应式媒体查询 (@media): 在小屏幕设备上,调整相册高度、缩略图大小和导航按钮大小,以获得更好的用户体验。

第三步:JavaScript 特效

我们用JavaScript来实现所有的交互逻辑,包括图片切换、自动播放、键盘控制和放大镜效果。

css网页动态相册js特效代码
(图片来源网络,侵删)
// script.js
document.addEventListener('DOMContentLoaded', () => {
    // --- 1. 获取DOM元素 ---
    const mainImage = document.getElementById('mainImage');
    const prevBtn = document.querySelector('.prev-btn');
    const nextBtn = document.querySelector('.next-btn');
    const currentIndexSpan = document.getElementById('currentIndex');
    const totalImagesSpan = document.getElementById('totalImages');
    const thumbnailList = document.querySelector('.thumbnail-list');
    const magnifierGlass = document.querySelector('.magnifier-glass');
    // --- 2. 图片数据 ---
    // 使用 picsum.photos 服务生成不同的图片
    const images = [
        { src: 'https://picsum.photos/seed/img1/800/500.jpg', thumb: 'https://picsum.photos/seed/img1/80/60.jpg' },
        { src: 'https://picsum.photos/seed/img2/800/500.jpg', thumb: 'https://picsum.photos/seed/img2/80/60.jpg' },
        { src: 'https://picsum.photos/seed/img3/800/500.jpg', thumb: 'https://picsum.photos/seed/img3/80/60.jpg' },
        { src: 'https://picsum.photos/seed/img4/800/500.jpg', thumb: 'https://picsum.photos/seed/img4/80/60.jpg' },
        { src: 'https://picsum.photos/seed/img5/800/500.jpg', thumb: 'https://picsum.photos/seed/img5/80/60.jpg' },
        { src: 'https://picsum.photos/seed/img6/800/500.jpg', thumb: 'https://picsum.photos/seed/img6/80/60.jpg' },
        { src: 'https://picsum.photos/seed/img7/800/500.jpg', thumb: 'https://picsum.photos/seed/img7/80/60.jpg' },
        { src: 'https://picsum.photos/seed/img8/800/500.jpg', thumb: 'https://picsum.photos/seed/img8/80/60.jpg' }
    ];
    let currentIndex = 0;
    let autoPlayInterval;
    // --- 3. 初始化函数 ---
    function init() {
        // 设置总图片数
        totalImagesSpan.textContent = images.length;
        // 生成缩略图
        images.forEach((image, index) => {
            const img = document.createElement('img');
            img.src = image.thumb;
            img.alt = `缩略图 ${index + 1}`;
            img.classList.add('thumbnail');
            if (index === 0) img.classList.add('active'); // 第一张默认激活
            img.addEventListener('click', () => showImage(index));
            thumbnailList.appendChild(img);
        });
        // 绑定事件监听器
        prevBtn.addEventListener('click', showPrevImage);
        nextBtn.addEventListener('click', showNextImage);
        // 键盘控制
        document.addEventListener('keydown', (e) => {
            if (e.key === 'ArrowLeft') showPrevImage();
            if (e.key === 'ArrowRight') showNextImage();
        });
        // 鼠标悬停事件(自动播放/暂停)
        const mainImageContainer = document.querySelector('.main-image-container');
        mainImageContainer.addEventListener('mouseenter', stopAutoPlay);
        mainImageContainer.addEventListener('mouseleave', startAutoPlay);
        // 放大镜事件
        mainImageContainer.addEventListener('mouseenter', startMagnifier);
        mainImageContainer.addEventListener('mouseleave', stopMagnifier);
        mainImageContainer.addEventListener('mousemove', moveMagnifier);
        // 启动自动播放
        startAutoPlay();
    }
    // --- 4. 核心功能函数 ---
    function showImage(index) {
        // 移除所有缩略图的active类
        document.querySelectorAll('.thumbnail').forEach(thumb => thumb.classList.remove('active'));
        // 添加active类到当前缩略图
        document.querySelectorAll('.thumbnail')[index].classList.add('active');
        // 更新计数器
        currentIndexSpan.textContent = index + 1;
        // 更新主图
        mainImage.style.opacity = 0; // 先淡出
        setTimeout(() => {
            mainImage.src = images[index].src;
            mainImage.style.opacity = 1; // 再淡入
        }, 500); // 与CSS中的过渡时间匹配
        currentIndex = index;
    }
    function showPrevImage() {
        const newIndex = (currentIndex - 1 + images.length) % images.length;
        showImage(newIndex);
    }
    function showNextImage() {
        const newIndex = (currentIndex + 1) % images.length;
        showImage(newIndex);
    }
    // --- 5. 自动播放功能 ---
    function startAutoPlay() {
        autoPlayInterval = setInterval(showNextImage, 3000); // 每3秒切换一次
    }
    function stopAutoPlay() {
        clearInterval(autoPlayInterval);
    }
    // --- 6. 放大镜特效 ---
    function startMagnifier() {
        magnifierGlass.style.display = "block";
    }
    function stopMagnifier() {
        magnifierGlass.style.display = "none";
    }
    function moveMagnifier(e) {
        const mainImageContainer = document.querySelector('.main-image-container');
        const rect = mainImageContainer.getBoundingClientRect();
        // 计算鼠标在容器内的相对位置
        let x = e.clientX - rect.left;
        let y = e.clientY - rect.top;
        // 防止放大镜移出容器边界
        if (x > mainImage.width - magnifierGlass.offsetWidth / 2) {
            x = mainImage.width - magnifierGlass.offsetWidth / 2;
        }
        if (x < magnifierGlass.offsetWidth / 2) {
            x = magnifierGlass.offsetWidth / 2;
        }
        if (y > mainImage.height - magnifierGlass.offsetHeight / 2) {
            y = mainImage.height - magnifierGlass.offsetHeight / 2;
        }
        if (y < magnifierGlass.offsetHeight / 2) {
            y = magnifierGlass.offsetHeight / 2;
        }
        // 设置放大镜的位置
        magnifierGlass.style.left = (x - magnifierGlass.offsetWidth / 2) + "px";
        magnifierGlass.style.top = (y - magnifierGlass.offsetHeight / 2) + "px";
        // 计算背景图片的位置,实现放大效果
        const bgX = -(x * 2 - magnifierGlass.offsetWidth / 2);
        const bgY = -(y * 2 - magnifierGlass.offsetHeight / 2);
        magnifierGlass.style.backgroundImage = `url(${mainImage.src})`;
        magnifierGlass.style.backgroundRepeat = "no-repeat";
        magnifierGlass.style.backgroundSize = `${mainImage.width * 2}px ${mainImage.height * 2}px`; // 放大2倍
        magnifierGlass.style.backgroundPosition = `${bgX}px ${bgY}px`;
    }
    // 启动应用
    init();
});

代码说明

  • 数据结构 (images 数组): 将图片的大图地址和小图地址存储在一个对象数组中,方便管理。
  • showImage(index) 函数: 这是相册的核心,它负责更新缩略图的高亮状态、计数器,并通过先设置opacity:0,再改变src,最后恢复opacity:1的方式,实现平滑的淡入淡出切换效果。
  • 自动播放: 使用 setInterval 定时调用 showNextImage,当鼠标悬停在相册上时,用 clearInterval 清除定时器来暂停播放;鼠标离开时重新启动。
  • 键盘控制: 监听 keydown 事件,当按下左右箭头键时,触发相应的图片切换函数。
  • 放大镜特效:
    • startMagnifier / stopMagnifier: 控制放大镜镜片的显示与隐藏。
    • moveMagnifier: 在鼠标移动时被调用,它计算鼠标位置,设置放大镜镜片的位置,并巧妙地使用 background-imagebackground-sizebackground-position 来创建一个放大2倍的局部视图。background-size 是原图的2倍,而 background-position 则根据鼠标位置反向移动,从而产生“放大镜跟随鼠标”的视觉效果。

如何使用

  1. 将上面三个代码块分别保存为 index.htmlstyle.cssscript.js 文件。
  2. 将这三个文件放在同一个文件夹中。
  3. 用浏览器打开 index.html 文件,即可看到动态相册的效果。

您可以根据需要轻松地修改 images 数组来替换您自己的图片,或者通过调整CSS中的数值来改变相册的外观、动画速度和放大倍率。

css网页动态相册js特效代码
(图片来源网络,侵删)