2401_87097828 2025-11-10 15:57 采纳率: 0%
浏览 7

vue3使用gsap滚动插件ScrollTrigger时,带动画的盒子在播放时会抖动是为什么

vue3使用gsap滚动插件ScrollTrigger时,带动画的盒子在播放时会抖动是为什么

<template>
  <!--主容器 -->
  <div class="home-container">
    <!-- 滚动容器 -->
    <div class="scrollbar-container" ref="scroll">
      <!-- 内容盒子 -->
      <div class="content-first">
        <!-- 第一个卡片区 -->
        <div class="content-first-card">
           <!-- 第一个卡片容器 -->
          <div class="content-first-card-one-inner">
            <div class="content-first-card-one"></div>
          </div>
           <!-- 第二个卡片容器 -->
          <div class="content-first-card-two-inner">
            <div class="content-first-card-two"></div>
          </div>
           <!-- 第三个卡片容器 -->
          <div class="content-first-card-three-inner">
            <div class="content-first-card-three"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>


```javascript

<script setup lang="ts">
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { onMounted, onUnmounted, ref, nextTick } from "vue";

gsap.registerPlugin(ScrollTrigger);

const scroll = ref<HTMLElement | null>(null);

// 滚动驱动动画
const scrollGsapAnimation = () => {
  const tl = gsap.timeline({
    scrollTrigger: {
      trigger: ".content-first",
      start: "top top",
      end: "+=3000",
      scrub: 1,
      pin: true,
      pinReparent: true,
      invalidateOnRefresh: true,
      pinType: "transform",
      anticipatePin: 1,
      scroller: scroll.value,
    },
  });

  tl.fromTo(
    ".content-first-card",
    { opacity: 0, scale: 1.1 },
    { opacity: 1, scale: 1, duration: 0.3, ease: "power3.out" }
  );

  tl.to(
    ".content-first-card-one-inner",
    {
      rotateY: 180,
      rotate: -15,
      y: 23,
      x: 10,
      transformOrigin: "center center",
      ease: "power3.inOut",
      duration: 0.4,
    },
    "<"
  )
    .to(
      ".content-first-card-two-inner",
      {
        rotateY: 180,
        transformOrigin: "center center",
        ease: "power3.inOut",
        duration: 0.4,
      },
      "<"
    )
    .to(
      ".content-first-card-three-inner",
      {
        rotateY: 180,
        rotate: 12,
        x: -10,
        y: 25,
        transformOrigin: "center center",
        ease: "power3.inOut",
        duration: 0.4,
      },
      "<"
    );
};

// 生命周期
let ctx: gsap.Context;

onMounted(async () => {
  await nextTick();
  ctx = gsap.context(() => {
    scrollGsapAnimation();
  });
});

onUnmounted(() => ctx && ctx.revert());
</script>


<style scoped lang="less">
.home-container {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-image: url("../assets/images/background-noise.webp");
  font-family: "ShanHaiZhongXia";
 transform: none !important;
  .scrollbar-container {
    width: 100%;
    height: 100%;
    overflow: scroll;
    transform: none !important;
  will-change: scroll-position;
  backface-visibility: hidden;
  }
}

.content-first {
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;

  .content-first-card {
    display: flex;
    gap: 40px;

    .content-first-card-one-inner,
    .content-first-card-two-inner,
    .content-first-card-three-inner {
      position: relative;
      width: 336px;
      height: 432px;
      perspective: 800px;
      transform-style: preserve-3d;
      transform-origin: center center;
      transform: translateZ(0);
  will-change: transform, opacity;
    }

    .content-first-card-one,
    .content-first-card-two,
    .content-first-card-three {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      backface-visibility: hidden;
      background-size: cover;
      background-position: center;
      border-radius: 15px;
    }

    .content-first-card-one {
      background-image: url("../assets/images/20250411140754174435167457701_01.jpg");
    }

    .content-first-card-two {
      background-image: url("../assets/images/20250411140754174435167457701_02.gif");
    }

    .content-first-card-three {
      background-image: url("../assets/images/20250411140754174435167457701_03.gif");
    }
  }
}
</style>

```

  • 写回答

4条回答 默认 最新

  • 阿里嘎多学长 2025-11-10 16:03
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    解决方案

    带动画的盒子在播放时会抖动,可能是由于以下原因:

    1. 滚动插件的冲突:当使用 ScrollTrigger 时,可能会与其他滚动插件或浏览器的滚动行为冲突,导致抖动。
    2. 动画的计算:当动画涉及到复杂的计算或依赖于滚动位置时,可能会导致抖动。
    3. 浏览器的渲染问题:浏览器的渲染问题,例如渲染延迟或重绘问题,可能会导致抖动。

    解决方法

    1. 检查滚动插件的配置:检查 ScrollTrigger 的配置是否正确,是否有冲突的配置。
    2. 优化动画的计算:尝试优化动画的计算,例如使用 gsapsnapease 选项。
    3. 使用 gsapforce3D 选项:尝试使用 gsapforce3D 选项,强制使用 3D 渲染,可能会解决渲染问题。
    4. 检查浏览器的版本:检查浏览器的版本是否支持最新的 gsap 版本。

    核心代码

    import { gsap } from 'gsap';
    
    // 使用 force3D 选项
    gsap.to('.box', {
      x: 100,
      duration: 1,
      force3D: true,
    });
    

    注意

    上述解决方法仅供参考,具体问题具体分析,可能需要根据实际情况进行调整。

    评论

报告相同问题?

问题事件

  • 创建了问题 11月10日