简单的视差滚动效果

视差滚动(Parallax Scrolling)是一种网页设计技术,通过让不同层级的元素以不同的速度移动,创造出深度和立体感。这种效果模拟了现实世界中远近物体移动速度不同的视觉现象。

继续向下滚动,你会注意到不同元素以不同速度移动。这种多层次的视觉效果能够增强用户的沉浸感,让网页浏览变得更加生动有趣。

1 视差滚动效果原理

这个页面包含三个主要的视差层:背景层(移动最慢)、中景层(浮动图形)和前景层(发光文字,移动最快)。每一层都有独立的移动速度,创造出丰富的空间感。

视差效果的核心在于利用 JavaScript 监听滚动事件,根据滚动距离动态调整各层的 transform 属性。速度因子(data-speed)越小,该层移动越慢,视觉上就显得越远。

2 实现步骤

第一步:基础HTML框架

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>视差滚动教程</title>
</head>
<body>
    <h1>开始构建</h1>
</body>
</html>
  • <!DOCTYPE html>:告诉浏览器这是HTML5文档
  • <meta charset="UTF-8">:设置字符编码为UTF-8
  • <meta name="viewport">:确保移动端正常显示

第二步:重置默认样式

添加CSS重置,消除浏览器默认边距:

html 复制代码
<style>
    /* 重置所有元素的默认样式 */
    * {
        margin: 0;           /* 去除外边距 */
        padding: 0;          /* 去除内边距 */
        box-sizing: border-box;  /* 边框包含在宽高内 */
    }
    
    body {
        background-color: #000;  /* 黑色背景 */
        overflow-x: hidden;      /* 隐藏横向滚动条 */
        overflow-y: scroll;      /* 显示纵向滚动条 */
        font-family: Arial, sans-serif;
    }
</style>
  • * 选择器:选中所有元素
  • box-sizing: border-box:让宽高计算包含border和padding
  • overflow-x: hidden:防止横向滚动

第三步:创建可滚动容器

创建一个高度很大的容器,让页面可以滚动:

html 复制代码
<body>
    <!-- 视差容器 - 高度是视口的5倍 -->
    <div class="parallax-container">
        <p style="color: white;">滚动测试</p>
    </div>
</body>

<style>
    .parallax-container {
        height: 500vh;  /* 500%视口高度 = 可以滚动很长 */
        position: relative;
        background: linear-gradient(to bottom, #000, #111);
    }
</style>

第四步:创建固定的视差层

添加第一个视差层(背景层):

html 复制代码
<div class="parallax-container">
    <!-- 背景层 -->
    <div class="parallax-layer layer-bg">
        <p style="color: white; text-align: center;">背景层</p>
    </div>
</div>

<style>
    /* 视差层的基础样式 */
    .parallax-layer {
        position: fixed;   /* 固定定位 - 关键! */
        top: 0;
        left: 0;
        width: 100%;
        height: 100vh;     /* 占满整个视口 */
        display: flex;
        justify-content: center;
        align-items: center;
    }
    
    /* 背景层样式 */
    .layer-bg {
        z-index: 1;        /* 最底层 */
        background: url('https://images.unsplash.com/photo-1419242902214-272b3f66ee7a?w=1200') center/cover;
        opacity: 0.3;      /* 半透明 */
    }
</style>

第五步:添加更多视差层

添加中景层和前景层:

html 复制代码
<div class="parallax-container">
    <!-- 背景层 -->
    <div class="parallax-layer layer-bg" data-speed="0.3"></div>
    
    <!-- 中景层 -->
    <div class="parallax-layer layer-middle" data-speed="0.5">
        <div style="width: 100px; height: 100px; background: rgba(255,0,255,0.5); border-radius: 50%;"></div>
    </div>
    
    <!-- 前景层 - 文字 -->
    <div class="parallax-layer layer-text" data-speed="0.8">
        <h1 style="color: white; font-size: 80px;">NATURE</h1>
    </div>
</div>

<style>
    .layer-middle {
        z-index: 2;  /* 中间层 */
    }
    
    .layer-text {
        z-index: 3;  /* 最上层 */
    }
</style>
  • data-speed="0.3":自定义数据属性,用于JavaScript读取速度
  • 三层结构:背景(z-index:1) < 中景(2) < 前景(3)

第六步:JavaScript实现视差移动

这是核心部分!添加JavaScript让层随滚动移动:

html 复制代码
<script>
    // 1. 获取所有视差层
    const parallaxLayers = document.querySelectorAll('.parallax-layer');
    
    // 2. 定义更新函数
    function updateParallax() {
        // 获取页面滚动的距离
        const scrolled = window.pageYOffset;
        
        console.log('滚动距离:', scrolled);  // 调试用
        
        // 遍历每一层
        parallaxLayers.forEach(layer => {
            // 获取该层的速度因子
            const speed = layer.dataset.speed || 0.5;
            
            // 计算该层应该移动的距离
            // 负号表示向上移动
            const yPos = -(scrolled * speed);
            
            // 应用变换
            layer.style.transform = `translateY(${yPos}px)`;
            
            console.log(`层级速度${speed}, 移动${yPos}px`);
        });
    }
    
    // 3. 监听滚动事件
    window.addEventListener('scroll', updateParallax);
</script>

步骤1:获取所有层次的元素

javascript 复制代码
const parallaxLayers = document.querySelectorAll('.parallax-layer');

步骤2:计算各个层次的元素的偏移两量

javascript 复制代码
const scrolled = window.pageYOffset;  // 例如:滚动了100px
const speed = 0.3;                     // 速度因子
const yPos = -(100 * 0.3);            // = -30px

步骤3:应用偏移量到 transform 变换

javascript 复制代码
layer.style.transform = `translateY(-30px)`;

第七步:性能优化

使用 requestAnimationFrame 优化滚动性能:

javascript 复制代码
window.addEventListener('scroll', () => {
    // requestAnimationFrame 确保动画流畅
    requestAnimationFrame(updateParallax);
});
  • 滚动事件触发非常频繁(每秒可能几十次)
  • requestAnimationFrame 让浏览器在合适的时机执行
  • 避免掉帧,保持60fps

第八步:添加发光文字效果

把之前的发光文字代码整合进来:

html 复制代码
<div class="parallax-layer layer-text" data-speed="0.8">
    <div class="text-container">
        <h1>NATURE</h1>
    </div>
</div>

<style>
    .text-container {
        font-size: 7vw;
        font-weight: bold;
    }
    
    .text-container h1 {
        margin: 0;
        /* 镂空效果 */
        background: url('https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200') center/cover;
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        
        /* 发光效果 */
        filter: drop-shadow(0 0 1vw #ff00ff) 
                drop-shadow(0 0 2vw #00ffff) 
                drop-shadow(0 0 3vw #ffff00);
        
        /* 动画 */
        animation: glow 3s ease-in-out infinite;
    }
    
    @keyframes glow {
        0%, 100% {
            filter: drop-shadow(0 0 1vw #ff00ff) 
                    drop-shadow(0 0 2vw #00ffff) 
                    drop-shadow(0 0 3vw #ffff00);
        }
        50% {
            filter: drop-shadow(0 0 2vw #ff00ff) 
                    drop-shadow(0 0 3vw #00ffff) 
                    drop-shadow(0 0 4vw #ffff00);
        }
    }
</style>

第九步:添加滚动提示

引导用户向下滚动:

html 复制代码
<div class="scroll-hint">向下滚动探索更多</div>

<style>
    .scroll-hint {
        position: fixed;
        bottom: 30px;
        left: 50%;
        transform: translateX(-50%);  /* 水平居中技巧 */
        z-index: 4;
        color: rgba(255, 255, 255, 0.6);
        font-size: 14px;
        animation: bounce 2s infinite;
    }
    
    /* 向下箭头 */
    .scroll-hint::after {
        content: '↓';
        display: block;
        font-size: 24px;
    }
    
    /* 弹跳动画 */
    @keyframes bounce {
        0%, 100% { transform: translateX(-50%) translateY(0); }
        50% { transform: translateX(-50%) translateY(10px); }
    }
</style>

<script>
    // 滚动后隐藏提示
    function updateParallax() {
        const scrolled = window.pageYOffset;
        
        // ... 之前的视差代码 ...
        
        // 隐藏提示
        const scrollHint = document.querySelector('.scroll-hint');
        if (scrolled > 100) {
            scrollHint.style.opacity = '0';
        } else {
            scrollHint.style.opacity = '1';
        }
    }
</script>
  • ::after:伪元素,在元素后面添加内容
  • content: '↓':插入箭头符号
  • translateX(-50%):配合 left: 50% 实现完美居中

第十步:添加内容卡片

在视差区域后添加可滚动的内容:

html 复制代码
<!-- 在 parallax-container 后面 -->
<div class="content-section">
    <div class="content-card">
        <h2>标题1</h2>
        <p>这是第一段内容...</p>
    </div>
    
    <div class="content-card">
        <h2>标题2</h2>
        <p>这是第二段内容...</p>
    </div>
</div>

<style>
    .content-section {
        position: relative;
        z-index: 5;           /* 在视差层之上 */
        margin-top: 100vh;    /* 从视口底部开始 */
        padding: 100px 20px;
        background: linear-gradient(to bottom, transparent, #000 20%, #000);
    }
    
    .content-card {
        max-width: 800px;
        margin: 0 auto 80px;
        padding: 40px;
        background: rgba(255, 255, 255, 0.05);  /* 半透明背景 */
        border: 1px solid rgba(255, 255, 255, 0.1);
        border-radius: 15px;
        backdrop-filter: blur(10px);  /* 毛玻璃效果 */
        color: #fff;
        
        /* 初始状态:不可见 */
        opacity: 0;
        transform: translateY(50px);
        transition: all 0.8s ease;
    }
    
    /* 可见状态 */
    .content-card.visible {
        opacity: 1;
        transform: translateY(0);
    }
</style>
  • backdrop-filter: blur(10px):毛玻璃效果(需要半透明背景)
  • transition:平滑过渡动画
  • 初始 opacity: 0 + JavaScript动态添加 visible 类

第十一步:卡片淡入动画

当卡片滚动到视口内时,让它淡入:

javascript 复制代码
function checkCardVisibility() {
    // 获取所有卡片
    const cards = document.querySelectorAll('.content-card');
    // 获取视口高度
    const windowHeight = window.innerHeight;
    
    cards.forEach(card => {
        // 获取卡片相对视口的位置
        const cardTop = card.getBoundingClientRect().top;
        
        // 如果卡片进入视口80%的位置
        if (cardTop < windowHeight * 0.8) {
            card.classList.add('visible');  // 添加可见类
        }
    });
}

// 在滚动时检查
window.addEventListener('scroll', () => {
    requestAnimationFrame(() => {
        updateParallax();
        checkCardVisibility();  // 新增
    });
});

// 页面加载时也检查一次
checkCardVisibility();
html 复制代码
card.getBoundingClientRect().top
  • 返回元素相对于视口顶部的距离
  • 如果元素在视口下方,值为正
  • 如果元素在视口上方,值为负
html 复制代码
if (cardTop < windowHeight * 0.8)
  • windowHeight * 0.8 = 视口高度的80%位置
  • 当卡片到达这个位置时触发动画
  • 提前触发让动画更自然

第十二步:添加浮动图形

在中景层添加浮动的彩色圆圈:

html 复制代码
<div class="parallax-layer layer-middle" data-speed="0.5">
    <div class="floating-shapes">
        <div class="shape"></div>
        <div class="shape"></div>
        <div class="shape"></div>
    </div>
</div>

<style>
    .floating-shapes {
        width: 100%;
        height: 100%;
        position: relative;
        overflow: hidden;
    }
    
    .shape {
        position: absolute;
        border-radius: 50%;  /* 圆形 */
        opacity: 0.2;
        animation: float 20s infinite ease-in-out;
    }
    
    /* 第一个圆 */
    .shape:nth-child(1) {
        width: 100px;
        height: 100px;
        background: radial-gradient(circle, #ff00ff, transparent);
        top: 20%;
        left: 10%;
        animation-delay: 0s;
    }
    
    /* 第二个圆 */
    .shape:nth-child(2) {
        width: 150px;
        height: 150px;
        background: radial-gradient(circle, #00ffff, transparent);
        top: 60%;
        right: 15%;
        animation-delay: -5s;  /* 负延迟 = 动画从中间开始 */
    }
    
    /* 第三个圆 */
    .shape:nth-child(3) {
        width: 80px;
        height: 80px;
        background: radial-gradient(circle, #ffff00, transparent);
        top: 40%;
        right: 30%;
        animation-delay: -10s;
    }
    
    /* 浮动动画 */
    @keyframes float {
        0%, 100% {
            transform: translateY(0) scale(1);
        }
        50% {
            transform: translateY(-50px) scale(1.2);
        }
    }
</style>
  • nth-child(1):选择第1个子元素
  • radial-gradient:径向渐变(从中心向外)
  • animation-delay: -5s:负延迟让动画错开

现在把所有步骤组合起来,你就得到了完整的视差滚动页面!

3 核心原理总结

视差公式元素移动距离 = 滚动距离 × 速度因子

关键技术点:

  • position: fixed - 让层固定在视口
  • window.pageYOffset - 获取滚动距离
  • transform: translateY() - 移动元素
  • data-speed - 存储速度因子
  • requestAnimationFrame - 优化性能
相关推荐
Forget_85502 小时前
RHEL——web应用服务器TOMCAT
java·前端·tomcat
myFirstName3 小时前
离谱!React中不起眼的[]和{}居然也会导致性能问题
前端
我是伪码农3 小时前
Vue 2.11
前端·javascript·vue.js
Amumu121383 小时前
CSS:字体属性
前端·css
凯里欧文4273 小时前
html与CSS伪类技巧
前端
UIUV3 小时前
构建Git AI提交助手:从零到全栈实现的学习笔记
前端·后端·typescript
wuhen_n3 小时前
JavaScript 防抖与节流进阶:从原理到实战
前端·javascript
百慕大三角3 小时前
AI Agent开发之向量检索:一篇讲清「稀疏 + 稠密 + Hybrid Search」怎么落地
前端·agent·ai编程
打瞌睡的朱尤3 小时前
Vue day11商品详细页,加入购物车,购物车
前端·javascript·vue.js