zlx362211854 / daily-study

每日一个知识点总结,以issue的形式体现
10 stars 6 forks source link

9.什么是视差滚动?如何实现视差滚动的效果? #27

Open roxy0724 opened 5 years ago

goldEli commented 5 years ago

视差就是两个图层,在不同的 Z 轴方向,滚动时的两个图层的速度会不一样,造成视觉差。

JavaScript 和 纯 CSS 都可以实现

JavaScript 的思路:监听 scroll 事件,延迟修改 DOM,造成视觉差。

纯 CSS 的思路:主要就是两个属性 perspectivetransform: translateZ()perspective:创建一个 3D 视窗,并且设置 overflow: scroll, 让窗内的内容可以滚动。transform: translateZ():为窗内的图层设置 Z轴 方向的位置。

纯 CSS 实现如下:

* {
  padding: 0;
  margin: 0;
}
.parallax {
  font-size: 400%;
  height: 800px;
  overflow: scroll;
  perspective: 1px;
}
.parallax__layer {
  padding: 800px 0;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
.parallax__layer--foreground {
  transform: translateZ(0);
}
.parallax__layer--background {
  background-color: aquamarine;
  transform: translateZ(-1px);
}
.title {
  position: absolute;
  left: 50%;
  top: 50%;
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}
<div class="parallax">
  <div class="parallax__layer parallax__layer--background">
    <div class="title">This is the background</div>
  </div>
  <div class="parallax__layer parallax__layer--foreground">
    <div class="title">This is the foreground</div>
  </div>
</div>

Reference

roxy0724 commented 5 years ago

时差滚动,是指让多层背景以不同速度移动,形成立体的背景效果,以带来视觉体验。

实现

zlx362211854 commented 5 years ago

视差滚动,其实原理源自生活中,举个例子: 我们坐在车上,车以60km的速度往前开,观察路旁的树,感觉景物倒退的速度很快,如果我们看远处的高楼,发现倒退的比较慢,虽然相对于路边的树和远处的高楼,同样我们都是以60km的速度离开,但是眼睛给我们的感觉,像是远处的景物离开的慢一点,其实这就是视差效果。 生活中这样的例子,举一反三到网页开发中来,如果我们能给两个物体设置离我们眼睛不同的距离,那么是否也可以出现视差效果呢? 先介绍perspective属性,定义3D元素离观察点的位置。使用这个属性,就能模拟出视差效果: scroll

上半部分滚动的快一点,下半部分慢一点,就产生了视差效果,具体代码:

html, body {
      width: 100%;
      height: 100%;
    }
    .container {
      width: 100%;
      height: 100%;
      overflow: scroll;
      background-color: aqua;
      perspective: 1px;
      text-align: center
    }
    .head>p {
      font-size: 40px;
      font-weight: 600;
    }
    .inner {
      transform: translateZ(-1px);
    }
    .inner>p {
      font-size: 40px;
      font-weight: 600;
    }
<div class="container">
  <div class="head">
      <p>杏花疏雨洒香堤,高楼帘幕垂。</p>
      <p>远山映水夕阳低,春愁压翠眉。</p>
      <p>芳草句,碧云辞,低徊闲自思。</p>
      <p>流莺枝上不曾啼,知君肠断时。</p>
  </div>

  <div class="inner">
    <p>日月如磨蚁</p>
    <p>万事且浮休。</p>
    <p>君看檐外江水,</p>
    <p>滚滚自东流。</p>
    <p>风雨瓢泉夜半,</p>
    <p>花草雪楼春到,</p>
    <p>老子已菟裘。</p>
    <p>岁晚问无恙,</p>
    <p>归计橘千头。</p>
    <p>日月如磨蚁</p>
    <p>万事且浮休。</p>
    <p>君看檐外江水,</p>
    <p>滚滚自东流。</p>
    <p>风雨瓢泉夜半,</p>
    <p>花草雪楼春到,</p>
    <p>老子已菟裘。</p>
    <p>岁晚问无恙,</p>
    <p>归计橘千头。</p>
  </div>
</div>

关键在于: perspective: 1px;定义了container容器距观察点的距离是1px,再将容器内的子元素inner使用transform属性设置为距离容器-1px:transform: translateZ(-1px); 空间位置示意: image

这样就实现了视差效果。