๊ฐ์ธํ๋ก์ ํธ
์ฌ์ดํธ๋ช : OUTFIT7
์์ ๊ธฐ๊ฐ: 7์ผ ์์
#gsap #canvas
์ ํ: ์ธํฐ๋ ํฐ๋ธํ pc ์ฌ์ดํธ
ํน์ง: canvas ์ gsap์ ์ฌ์ฉํ ๋ชจ์ ์ ์ฉ
hover ์, ์ ํํ๊ณ ์ถ์ ํญ๋ชฉ์ ์ ์ธํ ๋๋จธ์ง์ ์์์ ์ ์ง.
header .gnb-item:hover a{color: #fff;}
//์ ํํญ๋ชฉ์ :hover ๋ฅผ ์ ์ฉํด ์ฃผ๊ณ //
header .gnb-list:hover .gnb-item:not(:hover){color: rgba(242, 242, 242, 50%);}
//์์ ํด๋์ค์ :hover ์ ์ฉ ํ, ๋น์ ํ ํญ๋ชฉ์ :not ์ ํ์๋ฅผ ์ ์ฉ์์ผ :hover ๋ฅผ ์ ์ธํด ์ค๋ค.
๋ท ๋ฐฐ๊ฒฝ์ ์ด๋ฏธ์ง๊ฐ ์คํฌ๋กค์ ํ ๋๋ง๋ค ์ ์ ๋ณ๊ฒฝ๋๋ ํจ๊ณผ๋ฅผ ์ฃผ๊ณ ์ถ์๋ค!
๋คํํ outfit ํ์ด์ง์ ๊ฐ๋ฐ์ ๋ชจ๋์์ ๋ถ๋ฆฌ๋ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง๋ฅผ ์ป์ ์ ์์๋ค.
(์ด๋ ๊ฒ ํ๋ํ๋ ์ชผ๊ฐ์ง ์ด๋ฏธ์ง๊ฐ 240์ฅ ์ฌ์ฉ๋์๋ค...!)
const canvas = document.querySelector('#downloads-bg');
//์บ๋ฒ์ค ์์ญ ์ ํ
const ctx = canvas.getContext('2d');
// 2d๋ก ์ง์
canvas.width = 1440;
canvas.height = 1181;
const frameCount = 240; //์ด๋ฏธ์ง ์ด๊ฐ์
//padStart (3 = ์ธ์๋ฆฌ (240) ,
const currentFrame = (idx) => {
return `https://outfit7.com/img-sequence/desktop/desktop_${idx.toString().padStart(3, '0')}.png`;
}; // ๋ฆฌํด ํ์
const images = [];
const card = {
frame: 0,
};
// ๋ฐ๋ณต๋ฌธ ์ฌ์ฉํ์ฌ ๋ถ๋ฌ์ค๊ธฐ
// i < frameCount ์ผ ๋ i ์ฆ๊ฐ์ํค๊ธฐ
//์ด๋ฏธ์ง ๋ฏธ๋ฆฌ ๋ถ๋ฌ์ค๊ธฐ (์ด๋ฏธ์ง๊ฐ ๋ก๋๋๋ฉฐ ๊น๋นก์ด๋ ํจ๊ณผ๊ฐ ์๊ฒ๋)
for (let i = 0; i < frameCount; i++) {
const img = new Image();
img.src = currentFrame(i + 1);
images.push(img);
}
//Gsap ์คํฌ๋กคํธ๋ฆฌ๊ฑฐ๋ฅผ ํตํด ์คํฌ๋กค ์์ญ ์ก์์ฃผ๊ธฐ
gsap.to(card, {
frame: frameCount - 1,
snap: 'frame',
ease: 'none',
scrollTrigger: {
trigger: '.sc-downloads .sticky-area',
scrub: 1,
start: '0% 0%',
end: '100% 100%',
// markers:true,
},
onUpdate: render,
});
images[0].onload = render;
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(images[card.frame], 0, 0);
}
์คํฌ๋กค์ ํ ๋๋ง๋ค ํ ์คํธ ์์์ด ํ๋์ฉ ์ฑ์์ง๋ ํจ๊ณผ๋ฅผ ๋ง๋ค๊ณ ์ถ์๋ค!
//SplitType.js ํ์ผ์ ๋ถ๋ฌ์ ๊ธ์๋ฅผ ํ๋ํ๋ ์ชผ๊ฐ์ฃผ์๋ค
const downloadsText = new SplitType('.sc-downloads .slide-text .text-box span', { types: 'words, chars', });
// timeline -> ์๊ฐ์์๋๋ก ์คํ์์ผ์ฃผ๋๊ฒ ๋ชจ์
์ ๋คํจ๊ป ์จ์ค์์๋ค.
//ํ์๋ผ์ธ์ ํตํด ์คํฌ๋กค์ ๋ฐ๋ฅธ ํ
์คํธ์ ์์น ์ค์ ๊ณผ ์์ ๋ณ๊ฒฝ์ ์ ์ฉ!
const textMotion = gsap.timeline({
scrollTrigger:{
trigger: '.sc-downloads .sticky-area',
start:"0% 0%",
end:"100% 100%",
// markers:true,
scrub: 1,
},
})
textMotion.addLabel('a')
textMotion.to('.sc-downloads .slide-text',{ 'padding-top':73, },'a')
textMotion.to('.sc-downloads .slide-text .text-box .char',{color:'#fff', stagger:0.1 },'a')
// stagger๋ฅผ ํตํด ๊ธ์จ ์์์ ์์ฐจ์ ์ผ๋ก ๋ณ๊ฒฝ ์์ผ์ฃผ๊ธฐ
textMotion.to('.sc-downloads .bg-color',{yPercent:-100},'a')
์คํฌ๋กค์ ๋ง์ถฐ ์ค๋ผ๋ฝ ์ปค์ง๊ณ ๋ฑ์ฅํ๋ ์ญ๋์ ์ธ ๋ชจ์ !
gsap ์คํฌ๋กค ํธ๋ฆฌ๊ฑฐ + ํ์๋ผ์ธ์ ์ฌ์ฉํด ๋ง๋ ๋ชจ์ .
์ถ๊ฐ ๊ณต๋ถ ์๋ฃ :
https://velog.io/@oneuya/GSAP-์ฌ์ฉ๋ฒ-์์๋ณด๊ธฐ
const hyperdotMotion = gsap.timeline({
scrollTrigger:{
trigger: '.sc-hyperdot .hyper-inner',
start:"0% 0%",
end:"80% 100%",
// markers:true,
scrub: 1,
},
})
hyperdotMotion.to('.sc-hyperdot .bg-blue',{
scale:6
}) //ํ๋์ ๋๊ทธ๋ผ๋ฏธ๊ฐ ๋ฐฐ๊ฒฝ์ ๊ฝ ์ฑ์ฐ๊ฒ ์ค์ผ์ผ ํค์ฐ๊ธฐ
hyperdotMotion.to('.sc-hyperdot .card-list',0.4,{
scale:1,
opacity:1,
}) //์๋์ ์นด๋ ๋ด์ค์ ๋ถํฌ๋ช
๋๊ฐ ์กฐ์ ๋๋ฉฐ ์ฌ๋ผ์ค๊ธฐ