vue 스크롤 반응 애니메이션

해적왕·2023년 6월 18일
1

애니메이션

<div class="bar-content">
    <div class="bar" :style="[isMenuOpen ? {width:'70%'} : {width:'0%'}]" :class="[isMenuOpen ? 'complete': 'reset']">
    </div>
    <span>M2 칩 탑재 MacBook Pro 13</span>
    <div class="bar2" :class="[isMenuOpen ? 'complete': 'reset']">
    </div>
    <span>M1 칩 탑재 MacBook Pro 13</span>
    <h3>
        1.4배
    </h3>
</div>
import { ref, onMounted } from "vue";
import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);

const isMenuOpen = ref(false);

onMounted(() => {
  if (!isMenuOpen.value) {
    gsap.to(".bar-content .bar", {
      scrollTrigger: ".bar-content",
      y: 0,
      width: "70%",
      opacity: 1,
      duration: 2,
      delay: 0.5,
    });
  }
  requestAnimationFrame(() => {
    isMenuOpen.value = true;
  });
});

css

@keyframes slidein {
  from {
    width: 0%;
  }

  to {
    width: 70%;
  }
}

.bar-content .bar {
  background: linear-gradient(to right, #ffc600, #e8482e, #9c209d);
  border-radius: 30px;
  height: 8px;
  opacity: 0;
}

.bar-content .bar.reset {
  width: 0% !important;
}

.bar-content .bar.complete {
  animation-name: slidein;
  animation-duration: 3s;
}

동영상

     <div class="heat">
        <h5>열 효율</h5>
        <div class="heat-wrap">
          <div class="heat-video">
            <video
              ref="video"
              muted
              autoplay
              v-if="!showImage"
              @ended="handleVideoEnded"
            >
              <source
                type="video/webm"
                src="동영상"
              />
            </video>
            <img
              v-else
              src="동영상이 끝나고 보여질 이미지"
            />
          </div>
        </div>
      </div>
import { ref, onMounted } from "vue";
import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);

const video = ref(null);
const showImage = ref(false);

const playVideo = () => {
  showImage.value = false;
  video.value.play();
};

const handleVideoEnded = () => {
  showImage.value = true;
  video.value.pause();
};

onMounted(()=>{
	 gsap.to(".heat-video", {
    scrollTrigger: ".heat-video",
    onComplete: playVideo,
  });
})

<h1 :class="[textflow  ? 'flow' : null]">최대 20시간의 배터리 사용 시간으로 오래오래.</h1>
import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";
import { ref, onMounted } from "vue";

gsap.registerPlugin(ScrollTrigger);

const textflow = ref(false);

const textAnimation = () => {
  textflow.value = true;
};

onMounted(() => {
  gsap.to("h1", {
    scrollTrigger: "h1",
    onComplete: textAnimation,
  });
});

<style>
@keyframes textclip {
  to {
    background-position: center 100%;
  }
}

h1 {
  background: linear-gradient(to top, #4cd265 50%, #fff 50%);
  color: #fff;
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  display: inline-block;
  background-size: auto 200%;
  transform: translate(-50%, -50%);
}

h1.flow {
  animation: textclip 2s linear forwards;
}
</style>

텍스트

<template>
  <div class="security">
      <h1>MacBook Pro</h1>
      <h2>{{ privacyInfo }}.</h2>
      <span>
        ..텍스트..
      </span>
    </div>
</template>

<script setup>
import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";
import { ref, onMounted, watch } from "vue";

gsap.registerPlugin(ScrollTrigger);

const privacyInfo = ref("개인정보는철저하게 ");
const displayedLength = ref(1);
const privacyLength = ref(0);

onMounted(() => {
  gsap.to(privacyInfo, {
    duration: 1,
    scrollTrigger: {
      start: "top center",
      end: "center center",
      trigger: ".security",
      scrub: true,
      onUpdate: (self) => {
        let text = "개인정보는 철저하게";
        privacyLength.value = privacyInfo.value.length;
        displayedLength.value = Math.floor(self.progress * privacyLength.value);

        privacyInfo.value =
          text.slice(0, displayedLength.value) +
          "·".repeat(privacyLength.value - displayedLength.value);
      },
    },
  });
});
</script>
profile
프론트엔드

2개의 댓글

comment-user-thumbnail
2024년 8월 21일

안녕하세요 해적왕님
저 애니메이션 관련해서 검색 후 해적왕님 블로그 보고.. 넘나 팬 됐슴니다..❤️
매번 좋은 글 너무너무 감사합니다😍

1개의 답글