Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Ashon-G/0f9993a9b75d71c21aaa3a571576da2b to your computer and use it in GitHub Desktop.
Save Ashon-G/0f9993a9b75d71c21aaa3a571576da2b to your computer and use it in GitHub Desktop.
GSAP - Scroll animation - Svg clip path

GSAP - Scroll animation - Svg clip path

SOTD Challenge : Insprired by 2 Authenticators website animation (SOTD, Apr 11, 2023)

A Pen by Vashon Gonzales on CodePen.

License.

<main class="flex__col">
<nav class="menu flex">
<a href="#" class="menu__left">
Lorem ipsum
</a>
<ul class="menu__right flex">
<li><a href="#">Work</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
<section class="clip" id="clip1">
<div class="clip__inner flex__col">
<h1 class="flex">Find your star</h1>
<div class="clip__cols flex">
<p>
SOTD Challenge : Insprired by <a href="https://2authenticators.co/">2 Authenticators</a> website animation (SOTD, Apr 11, 2023)
<br/><br/>
First time exploring Morph SVG.
</p>
<p>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
<br/>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
</p>
</div>
</div>
</section>
<section class="clip__scroll flex__col" id="clip1__scroll">
<h2>Le glacier</h2>
<div class="clip__cols flex">
<p>
SOTD Challenge : Insprired by <a href="https://2authenticators.co/">2 Authenticators</a> website animation (SOTD, Apr 11, 2023)
<br/><br/>
First time exploring Morph SVG.
</p>
<p>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
<br/>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
</p>
</div>
</section>
<section class="clip__scroll flex__col" id="clip2__scroll">
<h2>Le lac</h2>
<div class="clip__cols flex">
<p>
SOTD Challenge : Insprired by <a href="https://2authenticators.co/">2 Authenticators</a> website animation (SOTD, Apr 11, 2023)
<br/><br/>
First time exploring Morph SVG.
</p>
<p>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
<br/>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
</p>
</div>
</section>
<section class="clip__scroll flex__col" id="clip3__scroll">
<h2>La montagne</h2>
<div class="clip__cols flex">
<p>
SOTD Challenge : Insprired by <a href="https://2authenticators.co/">2 Authenticators</a> website animation (SOTD, Apr 11, 2023)
<br/><br/>
First time exploring Morph SVG.
</p>
<p>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
<br/>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
</p>
</div>
</section>
<section class="clip__scroll flex__col" id="clip4__scroll">
<h2>L'océan</h2>
<div class="clip__cols flex">
<p>
SOTD Challenge : Insprired by <a href="https://2authenticators.co/">2 Authenticators</a> website animation (SOTD, Apr 11, 2023)
<br/><br/>
First time exploring Morph SVG.
</p>
<p>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
<br/>
Nulla hendrerit metus lacinia magna rhoncus suscipit. Sed faucibus posuere tempor. Ut suscipit et urna a gravida.
</p>
</div>
</section>
<figure class="starSvg" id="svg1">
<svg height="0" width="0">
<defs>
<clipPath id="svg__path" clipPathUnits="objectBoundingBox">
<path id="svg__rec" data-name="rec" d="M0,0H1V1H0Z"/>
<path id="svg__star" data-name="star" d="M 0.5 0.0390625 C 0.472656 0.214844 0.449219 0.320312 0.382812 0.382812 C 0.320312 0.449219 0.214844 0.472656 0.0390625 0.5 C 0.214844 0.527344 0.320312 0.550781 0.382812 0.617188 C 0.449219 0.679688 0.472656 0.785156 0.5 0.960938 C 0.527344 0.785156 0.550781 0.679688 0.617188 0.617188 C 0.679688 0.550781 0.785156 0.527344 0.960938 0.5 C 0.785156 0.472656 0.679688 0.449219 0.617188 0.382812 C 0.550781 0.320312 0.527344 0.214844 0.5 0.0390625 Z M 0.828125 0.171875 C 0.738281 0.238281 0.667969 0.285156 0.605469 0.3125 C 0.617188 0.328125 0.628906 0.34375 0.640625 0.359375 C 0.65625 0.371094 0.671875 0.382812 0.6875 0.394531 C 0.714844 0.332031 0.761719 0.261719 0.828125 0.171875 Z M 0.175781 0.175781 C 0.238281 0.261719 0.285156 0.332031 0.3125 0.394531 C 0.328125 0.382812 0.34375 0.371094 0.359375 0.359375 C 0.371094 0.34375 0.382812 0.328125 0.394531 0.3125 C 0.332031 0.285156 0.261719 0.238281 0.175781 0.175781 Z M 0.6875 0.605469 C 0.671875 0.617188 0.65625 0.628906 0.640625 0.640625 C 0.628906 0.65625 0.617188 0.671875 0.605469 0.6875 C 0.667969 0.714844 0.738281 0.761719 0.828125 0.828125 C 0.761719 0.738281 0.714844 0.667969 0.6875 0.605469 Z M 0.3125 0.605469 C 0.285156 0.667969 0.238281 0.738281 0.171875 0.828125 C 0.261719 0.761719 0.332031 0.714844 0.394531 0.6875 C 0.382812 0.671875 0.371094 0.65625 0.359375 0.640625 C 0.34375 0.628906 0.328125 0.617188 0.3125 0.605469 Z M 0.3125 0.605469 "/>
</clipPath>
</defs>
</svg>
<!--<img src="https://images.unsplash.com/photo-1681206691902-14878e9c28db?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80">-->
<video loop autoplay muted poster="https://images.unsplash.com/photo-1519681393784-d120267933ba?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80">
<source src="http://thenewcode.com/assets/videos/glacier.mp4" type="video/mp4">
</video>
</figure>
<figure class="starSvg" id="svg2">
<svg height="0" width="0">
<defs>
<clipPath id="svg__path2" clipPathUnits="objectBoundingBox">
<path id="svg__rec2" data-name="rec2" d="M0,0H1V1H0Z"/>
<path id="svg__star2" data-name="star2" d="M 0.5 0.0390625 C 0.472656 0.214844 0.449219 0.320312 0.382812 0.382812 C 0.320312 0.449219 0.214844 0.472656 0.0390625 0.5 C 0.214844 0.527344 0.320312 0.550781 0.382812 0.617188 C 0.449219 0.679688 0.472656 0.785156 0.5 0.960938 C 0.527344 0.785156 0.550781 0.679688 0.617188 0.617188 C 0.679688 0.550781 0.785156 0.527344 0.960938 0.5 C 0.785156 0.472656 0.679688 0.449219 0.617188 0.382812 C 0.550781 0.320312 0.527344 0.214844 0.5 0.0390625 Z M 0.828125 0.171875 C 0.738281 0.238281 0.667969 0.285156 0.605469 0.3125 C 0.617188 0.328125 0.628906 0.34375 0.640625 0.359375 C 0.65625 0.371094 0.671875 0.382812 0.6875 0.394531 C 0.714844 0.332031 0.761719 0.261719 0.828125 0.171875 Z M 0.175781 0.175781 C 0.238281 0.261719 0.285156 0.332031 0.3125 0.394531 C 0.328125 0.382812 0.34375 0.371094 0.359375 0.359375 C 0.371094 0.34375 0.382812 0.328125 0.394531 0.3125 C 0.332031 0.285156 0.261719 0.238281 0.175781 0.175781 Z M 0.6875 0.605469 C 0.671875 0.617188 0.65625 0.628906 0.640625 0.640625 C 0.628906 0.65625 0.617188 0.671875 0.605469 0.6875 C 0.667969 0.714844 0.738281 0.761719 0.828125 0.828125 C 0.761719 0.738281 0.714844 0.667969 0.6875 0.605469 Z M 0.3125 0.605469 C 0.285156 0.667969 0.238281 0.738281 0.171875 0.828125 C 0.261719 0.761719 0.332031 0.714844 0.394531 0.6875 C 0.382812 0.671875 0.371094 0.65625 0.359375 0.640625 C 0.34375 0.628906 0.328125 0.617188 0.3125 0.605469 Z M 0.3125 0.605469 "/>
</clipPath>
</defs>
</svg>
<!--<img src="https://images.unsplash.com/photo-1681140348839-42def79675a7?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=830&q=80">-->
<video loop autoplay muted poster="https://images.unsplash.com/photo-1494253188410-ff0cdea5499e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80">
<source src="http://thenewcode.com/assets/videos/lake.mp4" type="video/mp4">
</video>
</figure>
<figure class="starSvg" id="svg3">
<svg height="0" width="0">
<defs>
<clipPath id="svg__path3" clipPathUnits="objectBoundingBox">
<path id="svg__rec3" data-name="rec3" d="M0,0H1V1H0Z"/>
<path id="svg__star3" data-name="star3" d="M 0.5 0.0390625 C 0.472656 0.214844 0.449219 0.320312 0.382812 0.382812 C 0.320312 0.449219 0.214844 0.472656 0.0390625 0.5 C 0.214844 0.527344 0.320312 0.550781 0.382812 0.617188 C 0.449219 0.679688 0.472656 0.785156 0.5 0.960938 C 0.527344 0.785156 0.550781 0.679688 0.617188 0.617188 C 0.679688 0.550781 0.785156 0.527344 0.960938 0.5 C 0.785156 0.472656 0.679688 0.449219 0.617188 0.382812 C 0.550781 0.320312 0.527344 0.214844 0.5 0.0390625 Z M 0.828125 0.171875 C 0.738281 0.238281 0.667969 0.285156 0.605469 0.3125 C 0.617188 0.328125 0.628906 0.34375 0.640625 0.359375 C 0.65625 0.371094 0.671875 0.382812 0.6875 0.394531 C 0.714844 0.332031 0.761719 0.261719 0.828125 0.171875 Z M 0.175781 0.175781 C 0.238281 0.261719 0.285156 0.332031 0.3125 0.394531 C 0.328125 0.382812 0.34375 0.371094 0.359375 0.359375 C 0.371094 0.34375 0.382812 0.328125 0.394531 0.3125 C 0.332031 0.285156 0.261719 0.238281 0.175781 0.175781 Z M 0.6875 0.605469 C 0.671875 0.617188 0.65625 0.628906 0.640625 0.640625 C 0.628906 0.65625 0.617188 0.671875 0.605469 0.6875 C 0.667969 0.714844 0.738281 0.761719 0.828125 0.828125 C 0.761719 0.738281 0.714844 0.667969 0.6875 0.605469 Z M 0.3125 0.605469 C 0.285156 0.667969 0.238281 0.738281 0.171875 0.828125 C 0.261719 0.761719 0.332031 0.714844 0.394531 0.6875 C 0.382812 0.671875 0.371094 0.65625 0.359375 0.640625 C 0.34375 0.628906 0.328125 0.617188 0.3125 0.605469 Z M 0.3125 0.605469 "/>
</clipPath>
</defs>
</svg>
<!--<img src="https://images.unsplash.com/photo-1681140348839-42def79675a7?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=830&q=80">-->
<video loop autoplay muted poster="https://images.unsplash.com/photo-1487715433499-93acdc0bd7c3?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1844&q=80">
<source src="http://thenewcode.com/assets/videos/mountain.mp4" type="video/mp4">
</video>
</figure>
<figure class="starSvg" id="svg4">
<svg height="0" width="0">
<defs>
<clipPath id="svg__path4" clipPathUnits="objectBoundingBox">
<path id="svg__rec4" data-name="rec4" d="M0,0H1V1H0Z"/>
<path id="svg__star4" data-name="star4" d="M 0.5 0.0390625 C 0.472656 0.214844 0.449219 0.320312 0.382812 0.382812 C 0.320312 0.449219 0.214844 0.472656 0.0390625 0.5 C 0.214844 0.527344 0.320312 0.550781 0.382812 0.617188 C 0.449219 0.679688 0.472656 0.785156 0.5 0.960938 C 0.527344 0.785156 0.550781 0.679688 0.617188 0.617188 C 0.679688 0.550781 0.785156 0.527344 0.960938 0.5 C 0.785156 0.472656 0.679688 0.449219 0.617188 0.382812 C 0.550781 0.320312 0.527344 0.214844 0.5 0.0390625 Z M 0.828125 0.171875 C 0.738281 0.238281 0.667969 0.285156 0.605469 0.3125 C 0.617188 0.328125 0.628906 0.34375 0.640625 0.359375 C 0.65625 0.371094 0.671875 0.382812 0.6875 0.394531 C 0.714844 0.332031 0.761719 0.261719 0.828125 0.171875 Z M 0.175781 0.175781 C 0.238281 0.261719 0.285156 0.332031 0.3125 0.394531 C 0.328125 0.382812 0.34375 0.371094 0.359375 0.359375 C 0.371094 0.34375 0.382812 0.328125 0.394531 0.3125 C 0.332031 0.285156 0.261719 0.238281 0.175781 0.175781 Z M 0.6875 0.605469 C 0.671875 0.617188 0.65625 0.628906 0.640625 0.640625 C 0.628906 0.65625 0.617188 0.671875 0.605469 0.6875 C 0.667969 0.714844 0.738281 0.761719 0.828125 0.828125 C 0.761719 0.738281 0.714844 0.667969 0.6875 0.605469 Z M 0.3125 0.605469 C 0.285156 0.667969 0.238281 0.738281 0.171875 0.828125 C 0.261719 0.761719 0.332031 0.714844 0.394531 0.6875 C 0.382812 0.671875 0.371094 0.65625 0.359375 0.640625 C 0.34375 0.628906 0.328125 0.617188 0.3125 0.605469 Z M 0.3125 0.605469 "/>
</clipPath>
</defs>
</svg>
<!--<img src="https://images.unsplash.com/photo-1681140348839-42def79675a7?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=830&q=80">-->
<video loop autoplay muted poster="https://images.unsplash.com/photo-1503264116251-35a269479413?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80">
<source src="http://thenewcode.com/assets/videos/ocean-small.mp4" type="video/mp4">
</video>
</figure>
</main>
// First star
var svg1TL = gsap.timeline({scrollTrigger: {
trigger: "#clip1 .clip__inner",
scrub: 2,
pin: true,
pinSpacing: false,
invalidateOnRefresh: true
}})
svg1TL.fromTo("#svg1 video, #svg1 img", {y: "30%"}, {y: 0}, 0)
svg1TL.to("#svg__star", {morphSVG: {shape: "#svg__rec", origin: "50% 50%"}, ease: "none"}, 0);
svg1TL.fromTo("#svg1", {width: () => {if(window.innerWidth < 600) {return 70} else {return 200}}}, {width: () => {if(window.innerWidth < window.innerHeight){return "100vh"} else {return "100vw"}}, ease: "none"}, 0);
// Stars 2,3,4 could be in a function
// Second star
gsap.set("#svg2", {y: "100vh"})
gsap.to("#svg2", {y: 0, x: 0, scrollTrigger: {
trigger: "body",
scrub: true,
start: () => window.innerHeight * 2 + " bottom",
end: () => window.innerHeight * 3 + " bottom"
}, ease: "none"})
var svg2TL = gsap.timeline({scrollTrigger: {
trigger: "body",
scrub: 2,
start: () => window.innerHeight * 3 + " bottom",
end: () => window.innerHeight * 4 + " bottom",
invalidateOnRefresh: true
}})
svg2TL.fromTo("#svg2 video, #svg2 img", {y: "30%"}, {y: 0}, 0)
svg2TL.to("#svg__star2", {morphSVG: {shape: "#svg__rec2", origin: "50% 50%"}}, 0);
svg2TL.fromTo("#svg2", {width: () => {if(window.innerWidth < 600) {return 70} else {return 200}}}, {width: () => {if(window.innerWidth < window.innerHeight){return "100vh"} else {return "100vw"}}, ease: "none"}, 0);
// Third star
gsap.set("#svg3", {y: "100vh"})
gsap.to("#svg3", {y: 0, x: 0, scrollTrigger: {
trigger: "body",
scrub: true,
start: () => window.innerHeight * 4 + " bottom",
end: () => window.innerHeight * 5 + " bottom",
invalidateOnRefresh: true
}, ease: "none"})
var svg3TL = gsap.timeline({scrollTrigger: {
trigger: "body",
scrub: 2,
start: () => window.innerHeight * 5 + " bottom",
end: () => window.innerHeight * 6 + " bottom",
invalidateOnRefresh: true
}})
svg3TL.fromTo("#svg3 video, #svg3 img", {y: "30%"}, {y: 0}, 0)
svg3TL.to("#svg__star3", {morphSVG: {shape: "#svg__rec3", origin: "50% 50%"}}, 0);
svg3TL.fromTo("#svg3", {width: () => {if(window.innerWidth < 600) {return 70} else {return 200}}}, {width: () => {if(window.innerWidth < window.innerHeight){return "100vh"} else {return "100vw"}}, ease: "none"}, 0);
// Fourth star
gsap.set("#svg4", {y: () => window.innerHeight})
gsap.to("#svg4", {y: 0, x: 0, scrollTrigger: {
trigger: "body",
scrub: true,
start: () => window.innerHeight * 6 + " bottom",
end: () => window.innerHeight * 7 + " bottom"
}, ease: "none"})
var svg4TL = gsap.timeline({scrollTrigger: {
trigger: "body",
scrub: 2,
start: () => window.innerHeight * 7 + " bottom",
end: () => window.innerHeight * 8 + " bottom"
}})
svg4TL.fromTo("#svg4 video, #svg4 img", {y: "30%"}, {y: 0}, 0)
svg4TL.to("#svg__star4", {morphSVG: {shape: "#svg__rec4", origin: "50% 50%"}}, 0);
svg4TL.fromTo("#svg4", {width: () => {if(window.innerWidth < 600) {return 70} else {return 200}}}, {width: () => {if(window.innerWidth < window.innerHeight){return "100vh"} else {return "100vw"}}, ease: "none"}, 0);
<script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script>
<script src="https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js"></script>
<script src="https://assets.codepen.io/16327/MorphSVGPlugin3.min.js"></script>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap');
:root {
--font1: "Poppins";
--fontSizeMenu: 1vw;
--fontSizeH1: 10vw;
--fontSizeP: 1.48vw;
--maxWidth: 1100px;
}
body {
margin: 0;
background-color: #f7f0ea;
font-family: var(--font1);
overflow-x: hidden;
}
.flex, .flex__col {
display: flex;
justify-content: center;
align-items: center;
}
.flex__col {
flex-direction: column;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
main.flex__col {
width: 100%;
justify-content: flex-start;
}
.menu {
position: fixed;
z-index: 999;
top: 0;
left: 50%;
width: calc(100% - 80px);
justify-content: space-between;
margin: 40px 0;
transform: translatex(-50%);
}
.menu a {
font-size: var(--fontSizeMenu);
font-weight: 600;
color: var(--dark);
text-decoration: none;
}
.menu ul {
gap: 0 60px;
}
.menu ul li {
display: flex;
}
.clip {
width: 100%;
height: 150vh;
}
.clip__inner {
position: relative;
width: 100%;
height: 100vh;
}
.clip__inner h1 {
align-items: flex-end;
height: 40vh;
font-size: var(--fontSizeH1);
text-align: center;
max-width: var(--maxWidth);
margin: 5vw 0;
}
.clip__cols {
width: 70vw;
height: 45vh;
gap: 40px;
align-items: flex-start;
max-width: var(--maxWidth);
}
.clip__cols p {
font-size: var(--fontSizeP);
width: 50%;
}
.clip__cols a {
color: #000;
}
.clip__scroll {
z-index: 3;
width: 100vw;
height: 100vh;
padding-top: 100vh;
}
#clip1__scroll {
padding-top: 0;
}
.clip__scroll h2 {
color: #fff;
font-size: var(--fontSizeH1);
margin: 0 0 6vw 0;
}
.clip__scroll .clip__cols {
height: auto;
}
.clip__scroll p, .clip__scroll a {
color: #fff;
}
#svg__rec, #svg__rec2, #svg__rec3, #svg__rec4 {
display: none;
}
.starSvg {
position: fixed;
z-index: 2;
top: 50%;
left: 50%;
margin: 0;
width: 200px;
height: auto;
aspect-ratio: 1/1;
transform: translate(-50%, -50%);
}
#svg1 {clip-path: url(#svg__path)}
#svg2 {clip-path: url(#svg__path2)}
#svg3 {clip-path: url(#svg__path3)}
#svg4 {clip-path: url(#svg__path4)}
.starSvg img, .starSvg video {
position: absolute;
top: 50%;
left: 50%;
width: 100vw;
height: auto;
aspect-ratio: 1/1;
object-fit: cover;
transform: translate(-50%,-50%);
}
@media (orientation: portrait) {
.starSvg img, .starSvg video {
width: auto;
height: 100vh;
}
}
@media (min-width: 1550px) {
:root {
--fontSizeMenu: 16px;
--fontSizeH1: 140px;
--fontSizeP: 22px;
}
.clip__inner h1 {
height: 30vh;
}
.clip__cols {
height: 35vh;
}
}
@media (max-width: 600px) {
:root {
--fontSizeMenu: 11px;
--fontSizeP: 11px;
}
.menu {
width: 90vw;
margin: 4vw 0;
}
.menu ul {
gap: 0 2vw;
}
.clip__inner h1 {
width: 90vw;
justify-content: flex-start;
margin: 60px 0;
}
.clip__scroll h2 {
width: 90vw;
}
.clip__cols {
width: 90vw;
gap: 10px;
flex-direction: column;
justify-content: flex-start;
}
.clip__cols p {
width: 100%;
}
.starSvg {
width: 70px;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment