利用3D transform实现视差滚动

前言

最近在网页中运用『视差滚动』比较流行,能让网页有一种立体层次感

视差滚动(Parallax Scrolling)是指让多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。作为网页设计的热点趋势,越来越多的网站应用了这项技术。

——百度百科

说白了,『视差滚动』就是让同一页面的不同元素在滚动的时候,滚动速度各不相同,从而让人觉得页面有层次。然而css3新增的3D transform特性本身就可以为元素增加立体感,所以很适合用来实现『视差滚动』。

原理

相当于在同一三维坐标系中,为不同层次的元素设置不同的z坐标,就自然形成了不同的立体层面,滚动的时候不同z坐标的元素拥有不同的滚动速度(从结果上来说是这样的),且z坐标越小(即离屏幕平面向内越远)的平面,滚动速度看起来越慢

  1. 利用perspective属性构造一个相机(观察者)容器,然后设置perspective-origin(消失点?相机焦点?);
  2. 利用transform-style属性构造一个3d容器:
    1
    transform-style: preserve-3d;

也就是其内的元素呈现方式为3d,相当于构建了一个三维坐标系;

  1. 3d容器内利用transform: translateZ()设置不同的z坐标,体现层次;不过只设置z坐标,元素在投影到屏幕平面时,尺寸就不是原来的尺寸了,需要使用scale()进行缩放:

    1
    缩放系数 = (z坐标 - perspective设置值)/ perspective设置值
  2. 光有z坐标并不会自动按照z的大小进行层次覆盖,而是按照html的先后顺序进行覆盖,所以还需要按照层级手动添加z-index属性;

mark

实际上不同层面处于不同的z平面

mark

表面上看起来就是层叠

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#view{/* 相机容器 */
position: relative;
perspective: 300px;
perspective-origin: 0 0;
overflow-x: hidden;
overflow-y: scroll;
}
.layer{/* 3d容器 */
position: absolute;
left: 0;
width: 100%;
transform-style: preserve-3d;
}
.l1{/* 第一层级 */
transform: translateZ(0);
}
.l2{/* 第二层级 */
transform: translateZ(-300px) scale(2);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<section id="view">
<section class="layer">
<div class="l1">Layer 1</div>
<div class="l1">Layer 1</div>
<div class="l1">Layer 1</div>
<div class="l1">Layer 1</div>
<div class="l1">Layer 1</div>
</section>
<section class="layer">
<div class="l2">Layer 2</div>
<div class="l2">Layer 2</div>
<div class="l2">Layer 2</div>
</section>
</section>

查看demo

参考文档

  1. [译]高性能视差滚动|DuMengjie’s blog
  2. A grouped pure CSS parallax demo by Keith Clark