7
头图

滚动视差

介绍

视差滚动(Parallax Scrolling)是指多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。

实现原理

方式一:

利用 background-attachment 属性,我们可以把网页解刨成:背景层、内容层、悬浮层

background-attachment 的作用是设置背景图像随着页面滚动的时候固定,即使一个元素有滚动机制,背景也不会随着元素的内容而滚动,它的值有以下三个:

  • Scroll:默认值,背景图像会随着页面其余部分的滚动而移动。
  • fixed:当页面的其余部分滚动时,背景图像不会移动。
  • inherit:继承父元素 background-attachment 属性的值。

此实现方式可参考👇🏻

方式二:

配合使用 transformperspective 利用3D视图空间实现物体运动的速度差从而来实现视觉差效果。

原理如下:

transform: 可以对元素进行变换(2d/3d),包括平移 translate,旋转 rotate,缩放 scale,等等。

perspective : 当元素涉及 3d 变换时,它可以定义我们眼睛看到的 3d 立体效果,即空间感。

注意:当设置 translateZ 后,需要通过 scale 放大或者缩小元素来让元素达到肉眼所见的物体没被被放大缩小的感觉,计算 scale 的公式如下:

scale = ((translateZ * (-1)) / perspective) + 1

经典案例

  1. 利用background-attachment经典案例
  2. 这是一款名为Olija的游戏的网站,这是关于一个挥舞着鱼叉的英雄探索敌对土地以找到回家的路的故事。游戏有两个核心方面,首先是它的视觉流动性,其像素艺术中的像素尺寸相当大,因此如果不看到它的动态,就很难传达这款游戏的美感;第二个核心方面是它的故事。感觉就像游戏是根据已有的书籍或电视剧改编的。该网站的目标是抓住这两个核心方面,并吸引用户与之互动;让他们感觉自己是故事的一部分,并让他们感觉可以控制行动。

实战

视差动画demo-01

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            section {
                height: 100vh;
                background: rgba(0, 0, 0, .7);
                color: #fff;
                display: flex;
                justify-content: center;
                align-items: center;
                font-size: 20vh;
            }

            .img1 {
                background-image: url(https://qnm.xxx.com/Fkx77YvvfwdODmMvNVv_IaQx42wT);
                background-attachment: fixed;
                background-size: cover;
                background-position: center center;
            }

            .img2 {
                background-image: url(https://qnm.xxx.com/Fjh7nb4J7JonMOgGfbxXQU0WNRS0);
                background-attachment: fixed;
                background-size: cover;
                background-position: center center;
            }

            .img3 {
                background-image: url(https://qnm.xxx.com/lhXcD2QvakkntJVZMzyI2xiwEgic);
                background-attachment: fixed;
                background-size: cover;
                background-position: center center;
            }
        </style>
    </head>
    <body>
        <section class="text">1</section>
        <section class="img1">2</section>
        <section class="text">3</section>
        <section class="img2">4</section>
        <section class="text">5</section>
        <section class="img3">6</section>
        <section class="text">7</section>
    </body>
</html>

视差动画demo-02

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <style>
      #app {
        width: 100vw;
        height: 100vh;
        perspective: 1px;
        overflow-x: hidden;
        overflow-y: auto;
        transform-style: preserve-3d;
      }
      img {
        width: 100%;
        height: 100%;
      }
      .one {
        width: 100vw;
        height: 100vh;
        transform: translateZ(-1px) scale(2);
      }
      .two {
        width: 100vw;
        height: 100vh;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div class="one">
        <img
          src="https://qnm.xxx.com/FiRfmtOJCR62lDHO1hHrEg9kwPao"
          alt=""
        />
      </div>
      <div class="two">
        <img
          src="https://qnm.xxx.com/FuxV78Ht4u5EMKuupEzix6wYTQYF"
          alt=""
        />
      </div>
    </div>
  </body>
</html>

鼠标移动视差

案例

参考视差动画库parralax.js首页效果

原理

综合来看,其实主要还是围绕着监听鼠标移动事件——mousemove,通过获取实时的 clientXclientY 的偏移量来使当前画布中的参照物和物体实现一系列的变形(transform)的过程。

监听鼠标事件

window.onload = () => {
  // 监听鼠标在 pageX 容器移动
  pageX.addEventListener('mousemove', parallax, false)
}

旋转

// 旋转角度系数
let range = 40
// 旋转公式(返回-20 ~ 20,保留1为小数)
let calcValue = (a, b) => (a / b * range - range / 2).toFixed(1)
// 通过 calcValue 根据鼠标当前位置和容器宽高比计算得出的值
let xValue = calcValue(x, pageX.offsetWidth)
let yValue = calcValue(y, pageX.offsetHeight)
// 设置容器的旋转角度
cards.style.transform = "rotateX(" + yValue + "deg) rotateY(" + xValue + "deg)";

背景图偏移

bgContainer.style.backgroundPosition = xValue * .45 + "px " + -yValue * .45 + "px"

图片的位移

picItem.style.transform = "translateX(" + -xValue + "px) translateY(" + yValue + "px)"

源码

gitHub 仓库地址:https://github.com/cong1223/p...

参考文章

  1. stealing-game-animation-techniques-to-engage-users
  2. 视差特效的原理和实现方法


MangoGoing
774 声望1.2k 粉丝

开源项目:详见个人详情