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