โ Shrink Logo
โ GSAP์ toggleActions
โ scrollTrigger์์ ์ฌ์ฉ๋๋ ์ด๋ฒคํธ ์ฝ๋ฐฑ
โ ์คํฌ๋กค์์น์ ๋ฐ๋ฅธ ์์๋ณ๊ฒฝ
awwwards
๋ฅผ ๋๋ฌ๋ณด๋ ๋์ค์ ๊ตฌ์ฐ ํํ์ด์ง๋ฅผ ๋ค์ด๊ฐ ๋ณด๋ ๋ก๊ณ ๊ฐ ์คํฌ๋กค์ ํ๋ฉด ์ค์ด๋ค๊ฑฐ๋ ์ปค์ง๋ ์ ๋๋ฉ์ด์
์ด ๋์๋ค.
๊ทธ๋์ ์ด ํ๋ก์ ํธ์๋ ๊ตฌ์ฐ์ฒ๋ผ ๋ก๊ณ ์ ์ ๋๋ฉ์ด์
์ ์ฃผ๊ณ ์ถ์๋ค.
๋ํ, ํด๋น ์คํฌ๋กค์ ๋ค์ด๊ฐ๋ฉด ๋ก๊ณ ์ ๊ธ์์์๋ ๋ณ๊ฒฝ์ด ๋๊ฒ ํด๋ณด์๋ค.
const trigger = ScrollTrigger.create({
animation: gsap.from(".logo", {
y: "9vh", // ์ด๊ธฐ ์์น: y์ถ์ผ๋ก 9vh ์ด๋
scale: 13, // ์ด๊ธฐ ํฌ๊ธฐ: 13๋ฐฐ๋ก ํ๋
yPercent: -50, // ์ด๊ธฐ ์์น: y์ถ ๋ฐฉํฅ์ผ๋ก -50% ์ด๋
}),
scrub: 0.5,
trigger: ".sc-visual",
start: "center center",
endTrigger: ".sc-about",
end: "40% center",
});
// ๋ก๊ณ ์ ์์์ ๋ณ๊ฒฝํ๋ ํจ์๋ฅผ ์ ์
function changeColor(progress) {
gsap.to(".logo", {
color: progress >= 0.7 ? "#333" : "#fff",
duration: 0.3, // ๋ณ๊ฒฝ๋๋ ์์์ ๋ถ๋๋ฌ์ด ์ ํ์ ์ํ duration ์์ฑ
});
}
// ScrollTrigger์ onUpdate ์ฝ๋ฐฑ์ ํ์ฉํ์ฌ ๋ก๊ณ ์ ์์์ ๋ณ๊ฒฝํ๋ ํจ์๋ฅผ ํธ์ถ
trigger.animation.eventCallback("onUpdate", function () {
const triggerPosition = trigger.progress; // ํ์ฌ ScrollTrigger์ ์งํ ์ํ๋ฅผ ๊ฐ์ ธ์ ์ ์ฅ
changeColor(triggerPosition); // ์งํ ์ํ์ ๋ฐ๋ผ ๋ก๊ณ ์ ์์์ ๋ณ๊ฒฝํ๋ ํจ์ ํธ์ถ
});
forner studio ๋ฆฌ๋ด์ผ์ ์ ๋ฆฌํ ๋ ์ค๋ช
ํ์ง๋ง, ๋ค์ ์ ๋ฆฌ~~~
์์ฃผ ์ฐ์ด๋๋ฏ
progress
๋ GSAP์ ScrollTrigger์์ ์ ๊ณตํ๋ ์์ฑ ์ค ํ๋
ํ์ฌ ScrollTrigger์ ์ ๋๋ฉ์ด์ ์งํ ์ํ๋ฅผ ๋ํ๋ธ๋ค. ์ด ๊ฐ์ 0์์ 1 ์ฌ์ด์ ์ค์๋ก ํํ๋๊ณ ,
์คํฌ๋กค ์์น์ ๋ฐ๋ผ ์ด๋ ์ ๋ ์งํ๋์๋์ง๋ฅผ ๋ํ๋ธ๋ค.
์์
ScrollTrigger.create({
trigger: ".trigger",
start: "top center",
end: "+=500",
onUpdate: (self) => console.log("progress:", self.progress),
});
self
๋ GSAP์ ScrollTrigger ์ฝ๋ฐฑ ํจ์์์ ์ฌ์ฉ๋๋ ๋งค๊ฐ๋ณ์๋ก, ํด๋น ScrollTrigger ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
์ฆ, self
๋ฅผ ํตํด ScrollTrigger์ ์์ฑ ๋ฐ ๋ฉ์๋์ ์ ๊ทผํ ์ ์๋ค.
self.progress
๋ ํ์ฌ ScrollTrigger์ ์งํ ์ํ๋ฅผ ๋ํ๋ด๋ ์์ฑ์ผ๋ก, ์คํฌ๋กค ์งํ์ ๋ฐ๋ฅธ ๊ฐ์ด 0์์ 1๊น์ง ๋ณํ๋ค. ์์ ์ฝ๋์์๋ ์คํฌ๋กค ์งํ ์ํ๊ฐ ์
๋ฐ์ดํธ๋ ๋๋ง๋ค ์ฝ์์ ํ์ฌ progress
๊ฐ์ ์ถ๋ ฅํ๋๋ก ์ค์ .
self
๋ฅผ ์ด์ฉํ๋ฉด ScrollTrigger ์ฝ๋ฐฑ ํจ์์์ ๋ค์ํ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ ํ์ฉํ ์ ์๋ค. ์๋ฅผ ๋ค์ด, self.start
๋ฐ self.end
๋ฅผ ํตํด ์์ ๋ฐ ์ข
๋ฃ ์ง์ ์ ํ์ธํ๊ฑฐ๋, self.trigger
๋ฅผ ํตํด ํธ๋ฆฌ๊ฑฐ ์์์ ๋ํ ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค.
์คํฌ๋กค ๊ฐ์ ๋ฐ๋ผ ์ ๋๋ฉ์ด์
์ ์ค ๋ค๋ฅธ ํ๋ก์ ํธ๋ ์์ผ๋ ์ฐธ๊ณ ํ๊ธฐ~!!!
forner studio ๋ฆฌ๋ด์ผ
์ผ์ชฝ์ ๋ฐฐ๊ฒฝ์ด ์คํฌ๋กค ์ ์ธ๋ฑ์ค์ ๋ฐ๋ผ ๋ฐฐ๊ฒฝํ๋ฉด๊ณผ ๊ธ์์์์ด ๋ณ๊ฒฝ๋๊ฒ ํ๊ณ ์ถ์๋ค.
GSAP์ scrollTrigger์์ ์ฌ๋ฌ ์ด๋ฒคํธ ์ฝ๋ฐฑ๋ค์ด ์์๋๋ฐ ๊ทธ ์ค์ onToggle
์ ์ฌ์ฉํ์ฌ, ํด๋น์์ญ์ ํ ๊ธ์ด ๋๋ฉด ์ด๋ฒคํธ๊ฐ ๋ฐ์์ด ๋๊ฒํ์๋ค.
const infos = document.querySelectorAll(".info"); // ๋ชจ๋ .info ์์ ์ ํ
infos.forEach((info, index) => {
ScrollTrigger.create({
trigger: info,
start: "top center",
end: "bottom center",
// markers:true,
onToggle: (self) => {
const { isActive } = self; // ScrollTrigger์ ํ์ฑํ ์ํ ํ์ธ
let styles;
// ๊ฐ .info ์์์ ๋ฐ๋ผ ์คํ์ผ ์ง์
switch (index) {
// index๊ฐ 1์ธ ๊ฒฝ์ฐ
case 1:
styles = isActive
? { backgroundColor: "#e6e6e3", color: "#333" }
: { backgroundColor: "rgb(197, 37, 53)", color: "#fff" };
break;
// index๊ฐ 2์ธ ๊ฒฝ์ฐ
case 2:
styles = isActive
? { backgroundColor: "#c2a395", color: "#fff" }
: { backgroundColor: "rgb(197, 37, 53)", color: "#fff" };
break;
// index๊ฐ 3์ธ ๊ฒฝ์ฐ
case 3:
styles = isActive
? { backgroundColor: "#333333", color: "#fff" }
: { backgroundColor: "rgb(197, 37, 53)", color: "#fff" };
break;
// ๊ทธ ์ธ์ ๊ฒฝ์ฐ
default:
styles = { backgroundColor: "#c52535", color: "#fff" };
break;
}
gsap.to(".info", {
backgroundColor: styles.backgroundColor,
color: styles.color,
duration: 0.5,
ease: "power2.out",
});
},
});
});
.info
์์์ ๋ํด ScrollTrigger๋ฅผ ์์ฑํ๊ณ , ํด๋น ์์๊ฐ ํน์ ์ธ๋ฑ์ค ์คํฌ๋กค ์์น์ ๋๋ฌํ๊ฑฐ๋ ๋ ๋ ๋ ๋ฐ์ํ๋ onToggle
์ฝ๋ฐฑ์ ํตํด ์์์ ๋ฐ๋ผ ๋ค๋ฅธ ์คํ์ผ์ ์ ์ฉ.
์ด๋ฒคํธ์ฝ๋ฐฑ์ด ๋ฌด์์ผ๊น? ํ๋ฒ ์์๋ณด์~
onEnter: (self) => console.log("entered")
onLeave: (self) => console.log("left")
onEnterBack: (self) => console.log("entered back")
onLeaveBack: (self) => console.log("left back")
โญ5. onToggle:
onToggle: (self) => console.log("toggled, isActive:", self.isActive)