YSL

liimยท2023๋…„ 3์›” 27์ผ
0

๐Ÿ–ฅ YSL / ๋ฐ˜์‘ํ˜• PC

ํ•ด์™ธ ์‚ฌ์ดํŠธ๋ฅผ ๋ž˜ํผ๋Ÿฐ์Šค๋กœ ์ฐธ๊ณ ํ•˜์—ฌ ์ œ์ž‘ํ•œ ์ž…์ƒ๋กœ๋ž‘ ๋ทฐํ‹ฐ ์›น์‚ฌ์ดํŠธ


๐Ÿ“ข Check Point

  1. GSAP ํ…์ŠคํŠธ ์• ๋‹ˆ๋ฉ”์ด์…˜
  2. ์•„๋ž˜์—์„œ ์œ„๋กœ ์ฐจ์˜ค๋ฅด๋Š” ์˜์—ญ
  3. Swiper ์Šฌ๋ผ์ด๋“œ ๋””์ž์ธ
  4. matchMedia
  5. ๋™์ผ ๋ชจ์…˜ ํ•œ๋ฐฉ์— ์ฃผ๊ธฐ


1. GSAP ํ…์ŠคํŠธ ์• ๋‹ˆ๋ฉ”์ด์…˜

๐Ÿ‘‰ scrollTrigger

์Šคํฌ๋กค์„ ๋‚ด๋ฆฌ๊ณ  ์˜ฌ๋ฆผ์— ๋”ฐ๋ผ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ
์ž์„ธํ•œ ๊ธฐ๋Šฅ ์ •๋ฆฌ๋Š” ์—ฌ๊ธฐ ๐Ÿ‘‰ https://velog.io/@imyoox/GSAP-ScrollTrigger

<div class="cont-wrap">
    <div class="bg"></div>
    <div class="group-text inner">
        <h2 class="headline">
            <div class="text"><span>ONLY</span><span>AT</span></div>
            <div class="text lower"><span>YSL</span><span>beauty</span></div>
        </h2>
    </div>
</div>
gsap.set('.md-headline .text span',{yPercent:100})
intro = gsap.timeline({
    scrollTrigger:{
        trigger: ".sc-main-visual",
        start: "0% 0%",
        end: "+=500%",
        scrub: 1,
        pin: true,
    }
})

intro
.to('.headline .text span',{ yPercent:-100, stagger:0.05, opacity:0 })
.addLabel('a')
// ๋ฉ”์ธ ์‚ฌ์ง„์ด ์œ„๋กœ 10px ์˜ฌ๋ผ๊ฐ€๊ฒŒ
.to('.sc-main-visual .bg',3,{ yPercent:-10, },'a')
// ๊ฒ€์ • ๋ฐฐ๊ฒฝ ๋“ฑ์žฅ
.to('.sc-slogan.xs',3,{ opacity:1, visibility: 'visible' },'a')
// 4์ค„ ๋ฌธ์žฅ ์•„๋ž˜์—์„œ ์œ„๋กœ ๋“ฑ์žฅ
.to('.md-headline .text span',3,{ yPercent:0, stagger:0.05, },'a')
// 4์ค„ ๋ฌธ์žฅ ์œ„๋กœ ์‚ฌ๋ผ์ง
.to('.md-headline .text span',3,{ delay:1, yPercent:-100, stagger:0.05, })
  • gsap.set : GSAP ์‹คํ–‰ ์ „ ๋ฏธ๋ฆฌ ์…‹ํŒ…ํ•˜๋Š” ๊ฐ’
  • ".sc-main-visual" ์„น์…˜์„ ๊ธฐ์ค€์œผ๋กœ ํŠธ๋ฆฌ๊ฑฐ ์ž‘๋™
  • text๋ฅผ ๋‹จ์–ด๋งˆ๋‹ค span์œผ๋กœ ๊ฐ์‹ธ stagger ๊ฐ’์„ ์ฃผ์–ด, ์ „์ฒด๊ฐ€ ์•„๋‹Œ ๋“œ๋ฅด๋ฅต ๋‹จ๊ณ„์  ๋Š๋‚Œ์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ตฌํ˜„
  • ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ๋œ ์ˆœ์„œ๋Œ€๋กœ ์ด๋ค„์ง„๋‹ค.

addLabel('a')

a๊ฐ€ ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ๋Š” ์ˆœ์ฐจ๊ฐ€ ์•„๋‹Œ โ—๏ธ๋™์‹œ์—โ—๏ธ ํ•จ๊ป˜ ์ž‘๋™๋œ๋‹ค.


2. ์•„๋ž˜์—์„œ ์œ„๋กœ ์ฐจ์˜ค๋ฅด๋Š” ์˜์—ญ

๊ฐ๊ฐ์˜ ํŽ˜์ด์ง€๋ฅผ ํ™”๋ฉด ์•„๋ž˜์— ๋‚ด๋ ค๋†“์€ ๋’ค ์ˆœ์ฐจ์ ์œผ๋กœ ๋‚˜ํƒ€๋‚˜๊ฒŒ ํ•œ๋‹ค.

.sc-page-slide{
    position: absolute;
    top: 100vh; left: 0;
    width: 100%; height: 0;
    z-index: 10;
    padding: 0;
}
  • absolute top:100vh๋กœ ์ •ํ™•ํžˆ ํ™”๋ฉด ์•„๋ž˜์— ์œ„์น˜์‹œ์ผฐ๋‹ค.
.addLabel('a')
...(์ƒ๋žต)
.addLabel('b')
.to('.sc-page-slide .page1',3,{yPercent:-100, borderRadius:0 },'b')
.from('.sc-page-slide .page1 .headline',3,{ opacity:0, yPercent:100, },'b')
.to('.sc-page-slide .page2',3,{ yPercent:-100, borderRadius:0 })
.to('.sc-page-slide .page3',3,{ yPercent:-100, borderRadius:0 })
.to('.sc-page-slide .page4',3,{ yPercent:-100, borderRadius:0 })
.to('.sc-page-slide .group-page',{ yPercent:-100, borderRadius: '0 0 50% 50%' })
  • ์ฒ˜์Œ ์ด๋ฏธ์ง€์™€ ํ…์ŠคํŠธ๋Š” ๋™์‹œ์— ๋‚˜ํƒ€๋‚˜์•ผ ํ•จ์œผ๋กœ addLabel๋กœ ๋ฌถ์–ด์ฃผ์—ˆ๋‹ค.
  • ์ƒ๋‹จ ์–‘ ๋์ด ๋‘ฅ๊ทผ ํ˜•ํƒœ์—์„œ ์Šคํฌ๋กค 100%์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ ๊ฝ‰ ์ฑ„์›Œ์ง€๋„๋ก boderRadius๋ฅผ ์ฃผ์—ˆ๋‹ค.
&.page1{z-index: 1;}
&.page2{z-index: 2;}
&.page3{z-index: 3;}
&.page4{z-index: 4;}
  • ์Œ“์•„๊ฐ€๋Š” ๊ตฌ์„ฑ์„ ์œ„ํ•ด z-index๋ฅผ ์กฐ์ ˆํ•˜์˜€๋‹ค.


3. Swiper ์Šฌ๋ผ์ด๋“œ ๋””์ž์ธ

.swiper-slide-active img{
    transform: scale(1.2);
    border-radius: 600px;
    box-shadow: 0px 100px 100px rgb(0 0 0);
}

์Šฌ๋ผ์ด๋“œ๊ฐ€ active ๋˜์—ˆ์„ ๋•Œ
ํฌ๊ธฐ๋Š” 1.2๋ฐฐ๊ฐ€ ๋˜๊ณ , ๋ชจ์„œ๋ฆฌ๋Š” ๋” ๋‘ฅ๊ธ€๊ฒŒ, ๊ทธ๋ฆผ์ž๋ฅผ ์ฃผ์–ด ๋‹๋ณด์ด๋Š” ๊พธ๋ฐˆ ์š”์†Œ๋ฅผ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.


4. matchMedia

๐Ÿ‘‰ JavaScript์—์„œ์˜ ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ

JavaScript์—์„œ ๋ฐ˜์‘ํ˜• ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜์ด๋‹ค.
CSS์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฏธ๋””์–ด์ฟผ๋ฆฌ ์กฐ๊ฑด์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

gsap.registerPlugin(ScrollTrigger);
ScrollTrigger.matchMedia({

    "(min-width: 1280px)": function() {
		// 1280px ์ด์ƒ์ผ ๋•Œ
      	@content
    },

    "(min-width: 768px, max-width: 1279px)": function() {
        // 768px ์ด์ƒ, 1279px ์ดํ•˜์ผ ๋•Œ
      	@content
    },

    "all": function() {
        // ์ „์ฒด ํ•ด์ƒ๋„์—์„œ ์ ์šฉ
      	@content
    }

});
  • ๋ณธ์ธ์€ ๋ฉ”์ธ๊ณผ 2๋ฒˆ์งธ ํŽ˜์ด์ง€๋ฅผ ์ œ์™ธํ•œ scrollTrigger ๋ชจ์…˜์€ 1280px ์ด์ƒ์ผ ๋•Œ์—๋งŒ ์ž‘๋™ํ•˜๋„๋ก matchMedia๋ฅผ ํ™œ์šฉํ•˜์˜€๋‹ค.
  • gsap.set ๋ถ€ํ„ฐ intro ๋‚ด์šฉ ์ „์ฒด, ์ฆ‰ scrollTrigger ์Šคํฌ๋ฆฝํŠธ ์ „์ฒด๋ฅผ @content ์˜์—ญ์— ๊ธฐ์žฌํ•˜๋ฉด ๋œ๋‹ค.


5. ๋™์ผ ๋ชจ์…˜ ํ•œ๋ฐฉ์— ์ฃผ๊ธฐ

๊ฐ™์€ ๋ชจ์…˜์„ ๊ฐ€์ง„ ์˜์—ญ์ด ๋งŽ์„ ๋•Œ, ์ผ์ผ์ด ์„ ํƒํ•˜์ง€ ์•Š๊ณ  ํ•œ ๋ฒˆ์— ์ฃผ๋Š” ๋ฐฉ๋ฒ•

data-scroll ์ด๋ผ๋Š” data๊ฐ’์„ ๊ฐ™์€ ๋ชจ์…˜์ด ์ ์šฉ๋˜๋Š” ์˜์—ญ์— ๋ชจ๋‘ ๊ธฐ์žฌํ•œ๋‹ค.

[data-scroll]{
    overflow: hidden;
}
[data-scroll] span{
    display: block;
}

CSS ์Šคํƒ€์ผ ์ง€์ • ๊ฐ€๋Šฅ!

document.querySelectorAll('[data-scroll]').forEach(element => {
    child=element.children[0];
    
    gsap.from(child,{
        scrollTrigger:{
            trigger:element,
            start:"0% 80%", 
            end:"100% 100%",
            // markers:true,
            scrub:1,
        },
        yPercent:100,
        opacity:0,
    });
    
});

child=element.children[0];

ํƒ€๊ฒŸ์ด data-scroll์ด ์•„๋‹ˆ๊ณ  ๊ทธ ์ž์‹์ด๋ฏ€๋กœ children์œผ๋กœ ํ™•์ธํ•˜๋‹ˆ ๋ฐฐ์—ด์ด ์„ ํƒ๋œ๋‹ค.
ํƒ€๊ฒŸ์€ ๋ฐฐ์—ด์˜ ์ฒซ๋ฒˆ์งธ๋‹ˆ๊นŒ children[0] ์œผ๋กœ ์„ ํƒํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
forEach๋ฌธ์œผ๋กœ data-scroll ์ด๋ผ๋Š” ๊ฐ’์ด ์“ฐ์ธ ๊ฐœ์ฒด์— ๋ชจ๋‘ ๋ชจ์…˜์ด ๋“ค์–ด๊ฐ€๊ฒŒ ํ•˜์˜€๋‹ค.

profile
Web Publisher

0๊ฐœ์˜ ๋Œ“๊ธ€