官网GSAP.js初尝试 nuxtjs

仿照实现苹果音箱首页的滑动效果。因为没有接触过gsap就不知道有这东西,就打算自己用js写,写的很困难因为每个人的屏幕大小不一,本人的js水平也没很牛,导致写了很久虽然有效果但是不够流畅。后面上网搜了下意外发现gsap,看着案例慢慢试着写了写,终于实现了比之前的效果好。记录一下自己的实现:

1.配置文件nuxt.config.js引入gsap.js

{ src: "https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"},
{ src: "https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js" }

2.首页实现随着滑动,图片从下方移动到右中间,左侧同时出现步骤,右侧是图片,类似就是随着滑动两侧要同步图文注解。

<div class="yun-run">
          <div class="main">
            <div class="ywsy-scroll" ref="ywsyScroll">
              <p class="title" ref="ywsyTitle">业务上云</p>
              <div class="gdty">
                <p>滚动体验</p>
                <i class="iconfont icon-a-1_88"></i>
                <div class="line"></div>
              </div>
            </div>
            <div class="cloud-bz" ref="cloudBzScroll">
              <div class="text-bz-con" ref="textLeft">
                <div class="con">
                  <div class="left">
                    <div class="line"></div>
                    <div class="line-active"></div>
                    <ul class="title-list">
                      <li :class="{ 'active-li': imgActiveFlag == '1' }" @click="handleLineStep('1')">
                        <img v-if="imgActiveFlag == '1'" src="@/assets/index/cloud.webp" alt="" />
                        01 一键管理账号
                      </li>
                      <li :class="{ 'active-li': imgActiveFlag == '2' }" @click="handleLineStep('2')">
                        <img v-if="imgActiveFlag == '2'" src="@/assets/index/cloud.webp" alt="" />
                        02 自助授信,实时到账
                      </li>
                      <li :class="{ 'active-li': imgActiveFlag == '3' }" @click="handleLineStep('3')">
                        <img v-if="imgActiveFlag == '3'" src="@/assets/index/cloud.webp" alt="" />
                        03 余额预警,以防欠费
                      </li>
                      <li :class="{ 'active-li': imgActiveFlag == '4' }" @click="handleLineStep('4')">
                        <img v-if="imgActiveFlag == '4'" src="@/assets/index/cloud.webp" alt="" />
                        04 记录追溯,有迹可循
                      </li>
                      <li :class="{ 'active-li': imgActiveFlag == '5' }" @click="handleLineStep('5')">
                        <img v-if="imgActiveFlag == '5'" src="@/assets/index/cloud.webp" alt="" />
                        05 线上申请、下载发票
                      </li>
                      <li :class="{ 'active-li': imgActiveFlag == '6' }" @click="handleLineStep('6')">
                        <img v-if="imgActiveFlag == '6'" src="@/assets/index/cloud.webp" alt="" />
                        06 高效账单管理,便捷操作
                      </li>
                    </ul>
                  </div>
                </div>
              </div>
              <div class="img-con" ref="images">
                <img src="@/assets/index/bz-img1.webp" alt="" />
                <img src="@/assets/index/bz-img2.webp" alt="" />
                <img src="@/assets/index/bz-img3.webp" alt="" />
                <img src="@/assets/index/bz-img4.webp" alt="" />
                <img src="@/assets/index/bz-img5.webp" alt="" />
                <img src="@/assets/index/bz-img6.webp" alt="" />
              </div>
            </div>
          </div>
        </div>

js部分

animateElement() {
      const ywsyTitleText = this.$refs.ywsyTitle
      const ywsyScrollPart = this.$refs.ywsyScroll
      const cloudBzScrollPart = this.$refs.cloudBzScroll
      const textLeft = this.$refs.textLeft
      const images = Array.from(this.$refs.images.children)


      // ScrollTrigger for text scaling
      gsap.to(ywsyTitleText, { //根据滑动变化的DOM
        fontSize: '670px',
        scrollTrigger: {
          trigger: ywsyScrollPart, //触发的DOM
          start: 'top top',
          end: '+=670',
          scrub: true,
          pin: true
        },
      })

      // ScrollTrigger for complex image movement and text display
      gsap.timeline({
        scrollTrigger: {
          trigger: cloudBzScrollPart,
          start: 'top top',
          end: '+=7000',
          scrub: true,
          pin: true,
          // markers: true, // Remove this line in production; it's just for visualization
          onUpdate: (self) => {
            const scrollDirection = self.direction > 0 ? 'down' : 'up';

            const currentScroll = self.scroll()

            // Assuming each image section has a height of 100% of the viewport
            const sectionHeight = window.innerHeight

            let flag = Math.floor((currentScroll-3200) / sectionHeight) //3200自己慢慢调试效果
            if(flag < 0){
              flag = 1
            }
            if(flag > 6){
              flag = 6
            }

            // Calculate the active image flag based on scroll position
            this.imgActiveFlag = flag
          },
        }
      })
      .to(images[0], { opacity: 1 })
      .fromTo(
        images[0],
        { y: '0', x: '0' ,scale: '0.5'},
        { y: '-45%', x: '30%',scale: '1', duration: 100 }
      )
      .to(textLeft, { opacity: 1 })
      .fromTo(
        images[1],
        { y: '-45%', x: '30%' ,opacity: 0},
        { y: '-45%', x: '30%',opacity: 1 ,duration: 100 }
      )
      .fromTo(
        images[2],
        { y: '-45%', x: '30%' ,opacity: 0},
        { y: '-45%', x: '30%',opacity: 1 ,duration: 100 }
      )
      .fromTo(
        images[3],
        { y: '-45%', x: '30%' ,opacity: 0},
        { y: '-45%', x: '30%',opacity: 1 ,duration: 100 }
      )
      .fromTo(
        images[4],
        { y: '-45%', x: '30%' ,opacity: 0},
        { y: '-45%', x: '30%',opacity: 1 ,duration: 100}
      )
      .fromTo(
        images[5],
        { y: '-45%', x: '30%' ,opacity: 0},
        { y: '-45%', x: '30%',opacity: 1 ,duration: 100 }
      )
    }

scss部分

      .yun-run {
        .main {
          position: relative;
          height: 3260rem;
          .tab-fixed {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 1000rem;
            width: 100%;
            opacity: 1;
            background: url(../../assets/index/bg1.webp) no-repeat 100% 100%/100%
              100%;
            .title {
              text-align: center;
              font-size: 200rem;
              font-weight: 500;
              color: #ffffff;
              white-space: nowrap;
            }
          }
          .ywsy-scroll {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 1000rem;
            width: 100%;
            background: url(../../assets/index/bg1.webp) no-repeat 100% 100%/100%
              100%;
            .title {
              text-align: center;
              font-size: 200rem;
              font-weight: 500;
              color: #ffffff;
              white-space: nowrap;
            }
            .gdty {
              display: flex;
              flex-direction: column;
              justify-content: center;
              align-items: center;
              position: absolute;
              bottom: 0;
              left: 50%;
              transform: translateX(-50%);
              & > p {
                font-size: 20rem;
                font-weight: 400;
                line-height: 42rem;
                color: #ffffff;
              }
              & > i {
                margin: 20rem 0;
                font-size: 56rem;
                color: #fff;
              }
              .line {
                width: 1rem;
                height: 43rem;
                border-left: 3px dashed #ffffff;
              }
            }
          }
          .cloud-bz {
            display: flex;
            justify-content: space-around;
            align-items: center;
            background-color: #fafcff;
            width: 100%;
            height: 806rem;
            opacity: 1;
            .text-bz-con {
              position: absolute;
              left: 200rem;
              top: 158rem;
              opacity: 0;
              .con {
                .left {
                  display: flex;
                  .line {
                    position: absolute;
                    top: 8rem;
                    width: 2rem;
                    height: 600rem;
                    border: 2px dashed #dddddd;
                    left: 5rem;
                    z-index: -1;
                  }
                  .line-active {
                    position: absolute;
                    top: 8rem;
                    width: 2rem;
                    height: 0;
                    border: 2px dashed #4ca574;
                    left: 5rem;
                    z-index: 0;
                  }
                  .cloud-move {
                    position: absolute;
                    left: -16rem;
                    top: 8rem;
                    & > img {
                      width: 45.29rem;
                    }
                  }
                  .title-list {
                    height: 600rem;
                    display: flex;
                    flex-direction: column;
                    justify-content: space-between;
                    & > li {
                      font-size: 24rem;
                      line-height: 41rem;
                      color: #999999;
                      cursor: pointer;
                      &::before {
                        margin-right: 35rem;
                        display: inline-block;
                        content: '';
                        width: 15rem;
                        height: 15rem;
                        background: #4ca574;
                        border-radius: 50%;
                      }
                    }
                    .active-li {
                      position: relative;
                      font-size: 32rem;
                      line-height: 54rem;
                      color: #000000;
                      &>img {
                        position: absolute;
                        top: 10rem;
                        left: -16rem;
                      }
                    }
                  }
                }
              }
            }
            .img-con {
              display: flex;
              justify-content: space-around;
              position: relative;
              & > img {
                opacity: 0;
                transition: opacity 0.5s;
                position: absolute;
                width: 1144rem;
              }
            }
          }
        }
      }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值