专栏名称: VINCENT
目录
相关文章推荐
中国基金报  ·  深夜,跳水! ·  2 天前  
今天看啥  ›  专栏  ›  VINCENT

Nuxt 开发笔记 - 3 滚动交互动效

VINCENT  · 掘金  ·  · 2021-02-11 06:17

文章预览

阅读 26

Nuxt 开发笔记 - 3 滚动交互动效

本文主要介绍在 Nuxt 中使用 GSAP 和 vue-scrollmagic 插件实现较为复杂的页面滚动交互动效。

前排提示:

  • 操作系统:Windows 10
  • 编辑器:VS Code & HBuilder X
  • 使用版本:GSAP: 3.6.0vue-scrollmagic: 1.2.0

相关推荐:

预览

CodeSandbox: Nuxt 开发笔记 - 3 滚动交互动效

由于 GSAP 版本的问题,该项目导入 CodeSandbox 中无法直接预览,需要打开后在右下角控制台新建一个 Thermal 并输入 yarn dev 命令,最后刷新右上角预览页面。

文档

GSAP 官网vue-scrollmagicScrollMagic 官网

安装

vue-scrollmagic

详细安装步骤请见:vue-scrollmagic

下面只是笔者的使用方式,仅供参考。

# 安装 vue-scrollmagic 时会自动安装 ScrollMagic
$ yarn add vue-scrollmagic
复制代码

GSAP

详细安装步骤请见:GSAP

特别提示:直接使用 yarn add gsap 安装,得到的将是不包含 bonus plugins 的 gasp 版本。在 Nuxt 中将 gasp 搭配 vue-scrollmagic 使用必须安装包含 bonus plugins 的 gasp 版本,这需要注册登录后进行安装。

下面只是笔者的使用方式,仅供参考。

  1. 注册登录后进入 Dashboard 页面,这里提供 GSAP 压缩包 和 Token 两种方式

    Dashboard

  2. 通过 .npmrc 文件安装(个人推荐)

    在项目根目录新建 .npmrc 文件(笔者在 GitHub 中提供了自用的 .npmrc 文件,仅供个人学习使用,切勿他用)

    //npm.greensock.com/:_authToken=<token>
    @gsap:registry=https://npm.greensock.com
    复制代码

    打开终端

     # <package> 有以下选项 business, shockingly, simply, or member
     # 在官网 Dashboard 页面(上图)的右边栏中有标明,一般默认是 member。
         
     $ yarn add gsap@npm:@gsap/<package>
    复制代码
  3. 通过 gsap-bonus.tgz 文件安装

    在下载的压缩包里找到该文件,将其放到项目根目录下

    gsap-bonus.tgz

    打开终端

    $ yarn add ./gsap-bonus.tgz
    复制代码
  4. 步骤 2、3 选择一种即可,二者安装后的 package.json 文件中有一些差异 "gsap": "npm:@gsap/member" / "gsap": "file:gsap-bonus.tgz"

配置

详细配置步骤请见:vue-scrollmagic

下面只是笔者的使用方式,仅供参考。

  1. plugins 文件夹中新建 vue-scrollmagic.js 文件

    import Vue from "vue";
    import VueScrollmagic from "vue-scrollmagic";
    
    Vue.use(VueScrollmagic);
    复制代码
  2. 修改根目录中的 nuxt.config.js 文件

    plugins: [
      {
        src: "@/plugins/vue-scrollmagic.js",
        ssr: false
      }
    ],
    复制代码

使用

这里默认你已经会使用 ScrollMagic,否则建议请先前往 ScrollMagic 官网 快速入门。

  1. components 文件夹中创建 ScrollMagicBasic.vue 组件

    <template>
      <div>
        <div :class="`scroll-scene item-${scene.id}`"
             v-for="scene in sceneData"
             :key="scene.id">
          <h1>{{ scene.title }}</h1>
        </div>
      </div>
    </template>
        
    <script>
      export default {
        name: "ScrollMagicBasic",
        props: {
          sceneData: {
            type: Array,
            default: () => {
              return [];
            }
          }
        },
        mounted() {
          const that = this;
        
          that.scrollGsap();
        },
        methods: {
          scrollGsap() {
            const that = this;
        
            const slides = document.querySelectorAll(".scroll-scene");
            for (let i = 0; i < slides.length; i++) {
              that.$scrollmagic.addScene(
                that.$scrollmagic
                .scene({
                  triggerElement: slides[i],
                  triggerHook: "onLeave",
                  duration: "100%"
                })
                .setPin(slides[i], {
                  pushFollowers: false
                })
                // .addIndicators()  // 调试
              );
            }
          }
        }
      };
    </script>
        
    <style>
      .scroll-scene {
        height: 100vh;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
      }
    </style>
    复制代码
  2. pages 文件夹中的 index.vue 文件中使用该组件

    <template>
      <div>
        <div class="demo">
          <ScrollMagicBasic :sceneData="basicSceneData" />
        </div>
      </div>
    </template>
        
    <script>
      import ScrollMagicBasic from "@/components/ScrollMagicBasic";
        
      export default {
        data() {
          return {
            basicSceneData: [
              {
                id: 0,
                title: "scene item-0",
              },
              {
                id: 1,
                title: "scene item-1",
              },
              {
                id: 2,
                title: "scene item-2",
              },
              {
                id: 3,
                title: "scene item-3",
              }
            ]
          }
        },
        components: {
          ScrollMagicBasic
        }
      }
    </script>
        
    <style>
      .demo {
        position: relative;
        overflow: hidden;
        background-color: white;
      }
        
      .item-0 {
        background-color: teal;
      }
        
      .item-1 {
        background-color: thistle;
      }
        
      .item-2 {
        background-color: tomato;
      }
        
      .item-3 {
        background-color: turquoise;
      }
    </style>
    复制代码
  3. 效果预览(仅使用 vue-scrollmagic 实现的简单的滚动效果)

    vue-scrollmagic

  4. components 文件夹中创建 ScrollMagicAdvanced.vue 组件

    <template>
      <div>
        <div class="pin-wrap">
          <div class="scroll-wrap">
            <div :class="`scroll-part item-${scene.id}`"
                 v-for="scene in sceneData"
                 :key="scene.id">
              <h1>{{ scene.title }}</h1>
            </div>
          </div>
        </div>
      </div>
    </template>
       
    <script>
      export default {
        name: "ScrollMagicAdvanced",
        props: {
          sceneData: {
            type: Array,
            default: () => {
              return [];
            }
          }
        },
        mounted() {
          const that = this;
       
          that.scrollGsap();
        },
        methods: {
          scrollGsap() {
            const that = this;
            var tl = new TimelineMax({
              onUpdate: updatePercentage
            });
       
            tl.to(".scroll-wrap", 1, {x: "-12.5%"});
            tl.to(".scroll-wrap", 1, {x: "-25%"});
            tl.to(".scroll-wrap", 1, {x: "-37.5%"});
            tl.to(".scroll-wrap", 1, {x: "-50%"});
       
            const scene = that.$scrollmagic
              .scene({
                triggerElement: ".pin-wrap",
                triggerHook: "onLeave",
                duration: "400%"
              })
              .setPin(".pin-wrap")
              .setTween(tl);
            // .addIndicators();  // 调试
       
            that.$scrollmagic.addScene(scene);
       
            function updatePercentage() {
              tl.progress();
            }
          }
        }
      };
    </script>
       
    <style>
      .pin-wrap {
        width: 100%;
        height: 100vh;
        overflow: hidden;
        -webkit-perspective: 1000;
        perspective: 1000;
      }
       
      .scroll-wrap {
        width: 200%;
        height: 100vh;
      }
       
      .scroll-part {
        width: 12.5%;
        height: 100vh;
        float: left;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
      }
    </style>
    复制代码
  5. pages 文件夹中的 index.vue 文件中使用该组件

    <template>
      <div>
        <div class="demo">
          <ScrollMagicAdvanced :sceneData="advancedSceneData">
          </ScrollMagicAdvanced>
        </div>
      </div>
    </template>
        
    <script>
      import ScrollMagicAdvanced from "@/components/ScrollMagicAdvanced";
        
      export default {
        data() {
          return {
            advancedSceneData: [{
                id: 0,
                title: "part item-0",
              },
              {
                id: 1,
                title: "part item-1",
              },
              {
                id: 2,
                title: "part item-2",
              },
              {
                id: 3,
                title: "part item-3",
              },
              {
                id: 4,
                title: "part item-4",
              },
              {
                id: 5,
                title: "part item-5",
              },
              {
                id: 6,
                title: "part item-6",
              },
              {
                id: 7,
                title: "part item-7",
              }
            ]
          }
        },
        components: {
          ScrollMagicBasic,
          ScrollMagicAdvanced
        }
      }
    </script>
        
    <style>
      .demo {
        position: relative;
        overflow: hidden;
        background-color: white;
      }
        
      .item-0 {
        background-color: teal;
      }
        
      .item-1 {
        background-color: thistle;
      }
        
      .item-2 {
        background-color: tomato;
      }
        
      .item-3 {
        background-color: turquoise;
      }
        
      .item-4 {
        background-color: violet;
      }
        
      .item-5 {
        background-color: wheat;
      }
        
      .item-6 {
        background-color: yellow;
      }
        
      .item-7 {
        background-color: yellowgreen;
      }
    </style>
    复制代码
  6. 效果预览(vue-scrollmagic 搭配 gsap 实现的复杂的滚动效果)

    vue-scrollmagic 搭配 gsap

  7. 更多效果请前参见 ScrollMagic 官网 提供的官方案例

源码

GitHub:Nuxt 开发笔记 - 3 滚动交互动效

………………………………

原文地址:访问原文地址
快照地址: 访问文章快照
总结与预览地址:访问总结与预览