龙空技术网

我使用 Vue 实现了原神官网的全屏滚动效果

前端Tom 244

前言:

当前各位老铁们对“js判断全屏”都比较注重,我们都想要学习一些“js判断全屏”的相关资讯。那么小编同时在网摘上网罗了一些对于“js判断全屏””的相关文章,希望兄弟们能喜欢,我们快快来了解一下吧!

先看一下官网效果:

概念

每次当滚动鼠标滚轮的时候,页面会进行一整页的滚动,这就是全屏滚动。

要求

当窗口大小变化时,全屏滚动效果不会发生变化,即需要做到自适应,不受到高度宽度的影响。

当点击指示器也可以进行页面切换。

原理

最外层容器:就是我们的窗口,视角能看到的。

内层容器: 用来存放我们需要滚动内容的容器。

滚动元素: 就是我们看到的一张张照片。

首先对最外侧容器的overflow:hidden;这样保证不会溢出。

其次对内层容器进行滚动,每次滚动的高度就是窗口的高度,但是需要动态计算窗口的高度。

最后只需要判断上一页还是下一页来计算index,通过index ✖ 页面高度,来进行滚动即可。

代码实现HTML代码

大家可以结合html结构,去理解 js 代码

HTML复制代码<template>  <!-- 最外层容器 -->  <div class="outer-box" ref="fullPage">    <!-- 内层容器 -->    <div ref="element" :class="{ activeTranstion: isTranstion }" class="inner-box" @mousewheel="mousewheel">      <!-- 滚动显示的元素 -->      <div        v-for="item in ysImage"        :style="{ backgroundImage: `url(${item.backgroundImage})` }"        class="scroll-element"      ></div>    </div>    <!-- 指示器 -->    <ul class="aside">      <li v-for="(item, index) in asideData" @click="changeBac(index)">        <span :class="{ active: index === $index }"></span>        <div class="show-dec">{{ item.title }}</div>      </li>    </ul>  </div></template>
JS代码给内层容器添加鼠标滚动事件

当滚动事件触发时判断是向上还是向下滚动,以此来控制滚动方向。

另外由于鼠标滚动事件触发过于频繁,我们需要增加节流,即保证在单位时间内只执行一次即可。

设置canRun为节流标志,每500毫秒执行一次。

JS复制代码    function mousewheel(e) {      isTranstion.value = false      if (canRun.value) {        canRun.value = false        goScroll(e)        setTimeout(() => {          canRun.value = true        }, 1100)      }    }
开始滚动元素

通过上一页下一页增加减少$index,通过索引 ✖ 页面高度,来决定页面滚动的距离,也就是当前要显示的页面。

JS复制代码    function goScroll(e) {      //e.wheelDelta 用来判断上一个下一个 <0 下一个 >0上一个      if (e.wheelDelta < 0) {        next()      } else {        last()      }    }    //$INDEX    const $index = ref(0) //索引控制第几个显示    // 下一个    function next() {      if ($index.value < 4) {        $index.value++      }    }    // 上一个    function last() {      if ($index.value > 1 || $index.value === 1) {        $index.value--      }    }
动态计算页面高度

由于页面高度发生变化时,我们需要动态响应高度的变化。

使用 VueUse 库提供的 useWindowSize() 函数计算vueuse.org/core/useWin…

当页面高度变化时height会相应变化

JS复制代码    const { height } = useWindowSize()

值得注意的是,当页面高度变化时,我们需要关闭动画效果。

JS复制代码    const windowHeight = computed(() => {      isTranstion.value = true      return height.value    })

通过索引计算滚动高度

JS复制代码    const transformScroll = computed(() => {      return `translateY(-${$index.value * windowHeight.value}px)`    })

将滚动高度应用到滚动容器上面

watchEffect: 会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。官方:cn.vuejs.org/guide/essen…

JS复制代码    // ELEMENT    const element = ref('element')    watchEffect(() => {      if (element.value.style) {        element.value.style.transform = transformScroll.value      }    })
点击指示器

点击指示器的时候,跳转到相应页面,只需设置相应的index即可。

JS复制代码    // 点击切换    function changeBac(index) {      // 点击切换时需要开启动画      isTranstion.value = false      $index.value = index    }
效果(PC端)

想看效果得可以进入看一下:chenyajun.fun/#/fullPage

总结

全屏滚动的核心还是判断上一页还是下一页,动态计算页面高度,对内层容器进行滚动,从而显示我们需要展示的元素即可。

写作不易,你的赞就是我最大的动力,觉得写的不错的,可以给点个赞呢~

全部源码

HTML复制代码<script setup>// IMAGE DATAconst ysImage = ref([  {    backgroundImage: ';,  },  {    backgroundImage: ';,  },  {    backgroundImage: ';,  },  {    backgroundImage: ';,  },  {    backgroundImage:      ';,  },])const asideData = ref([  {    title: '蒙德',  },  {    title: '璃月',  },  {    title: '稻妻',  },  {    title: '须弥',  },  {    title: '枫丹',  },])// ELEMENTconst element = ref('element')watchEffect(() => {  if (element.value.style) {    element.value.style.transform = transformScroll.value  }})//HEIGHTconst { height } = useWindowSize()const windowHeight = computed(() => {  // 高度变化时需要关闭动画  isTranstion.value = true  return height.value})const transformScroll = computed(() => {  return `translateY(-${$index.value * windowHeight.value}px)`})// ISTRANSTION  CANRUNconst isTranstion = ref(false) //控制是否显示动画效果const canRun = ref(true) //节流控制器function mousewheel(e) {  isTranstion.value = false  if (canRun.value) {    canRun.value = false    goScroll(e)    setTimeout(() => {      canRun.value = true    }, 500)  }}function goScroll(e) {  //e.wheelDelta 用来判断上一个下一个 <0 下一个 >0上一个  if (e.wheelDelta < 0) {    next()  } else {    last()  }}//$INDEXconst $index = ref(0) //索引控制第几个显示// 下一个function next() {  if ($index.value < 4) {    $index.value++  }}// 上一个function last() {  if ($index.value > 1 || $index.value === 1) {    $index.value--  }}// 点击切换function changeBac(index) {  // 点击切换时需要开启动画  isTranstion.value = false  $index.value = index}</script><template>  <!-- 最外层容器 -->  <div class="outer-box" ref="fullPage">    <!-- 内层容器 -->    <div ref="element" :class="{ activeTranstion: isTranstion }" class="inner-box" @mousewheel="mousewheel">      <!-- 滚动显示的元素 -->      <div        v-for="item in ysImage"        :style="{ backgroundImage: `url(${item.backgroundImage})` }"        class="scroll-element"      ></div>    </div>    <!-- 指示器 -->    <ul class="aside">      <li v-for="(item, index) in asideData" @click="changeBac(index)">        <span :class="{ active: index === $index }"></span>        <div class="show-dec">{{ item.title }}</div>      </li>    </ul>  </div></template><style lang="scss" scoped>.activeTranstion {  transition: all 0ms ease 0s !important;}.active {  width: 12px !important;  height: 12px !important;}.outer-box {  width: 100%;  height: 100%;  overflow: hidden;  position: relative;  .inner-box {    width: 100%;    height: 100%;    transition: all ease-in-out 0.5s;    .scroll-element {      height: 100%;      background-size: cover !important;      background-position: center;      background-repeat: no-repeat;    }  }  .aside {    list-style: none;    position: fixed;    right: 20px;    top: 50%;    transform: translateY(-50%);    li {      height: 14px;      width: 14px;      margin: 7px;      display: flex;      align-items: center;      justify-content: center;      position: relative;      .show-dec {        position: absolute;        font-size: 10px;        width: 45px;        right: 20px;        opacity: 0;        color: #fff;        transition: all linear 0.1s;      }      span {        border-radius: 100%;        border: #fff solid 1px;        width: 4px;        height: 4px;        display: inline-block;        background-color: #fff;        transition: all ease-in-out 0.2s;      }      &:hover span {        width: 10px;        height: 10px;        background-color: #fff;        cursor: pointer;      }      &:hover .show-dec {        opacity: 1;      }    }  }}</style>

标签: #js判断全屏 #css整页滚动 #css背景图片全屏并可以滚动