MMCA 국립현대미술관 (반응형, Renewal)

Jiwon Hwang·2023년 3월 30일
0

portpolio

목록 보기
3/4

📚 Summary

사이트명 : MMCA 국립현대미술관 (반응형, Renewal)
작업 기간 : 23.03.13 ~ 23.03.16 (4일 소요)
사용언어: HTML, CSS, Jquery, Gsap, JS
유형 : 반응형, 리뉴얼
특징 : gsap를 활용해 다양한 스크롤 이벤트를 구현한 동적인 페이지입니다.

✔️ Main Point

  1. 첫 로드 시 나타나는 Header 메뉴, 그리고 가득 채워지는 도형 Motion
  2. Section 마다의 GSAP 스크롤 이벤트
  3. Click Event - Supscribe 모달창, 아코디언메뉴
  4. 이메일 팝업창 구현
  5. 반응형 구현 (media Query)


1. 첫 로드 시 나타나는 Header 메뉴, 그리고 가득 채워지는 도형 Motion

📋 첫 로드시에 Header 메뉴가 부드럽게 나타나고, 왼쪽 영역의 텍스트들과 오른쪽 영역에서의 도형들이 부드럽게 나타나는 모션을 구현하였습니다 .

◻️ CSS

CSS에서 도형요소마다 다른 위치와 크기를 설정해 주었습니다.

◻️ SCRIPT

$(function(){
    
    // header, main visual motion 
    introMotion = gsap.timeline({})
    introMotion
    .addLabel('a')
    .from('.header .inner',{ y: -30, opacity : 1, },'a') 
    .from('.sc-hero .sub-tit, .sc-hero .btn-wrap',{ x: -170 },'a')
    .from('.sc-hero .tit01, .sc-hero .tit04',{ x: 100 },'a')
    .from('.sc-hero .elem08',{ height:0 },'a')
    .from('.sc-hero .elem04, .sc-hero .elem10, .sc-hero .elem12',{ scale:0 },'a') 
    .from('.sc-hero .circle01.top, .sc-hero .circle01.btm',{ rotateZ: 180 },'a') 
    .from('.sc-hero .hero-elem.elem02, .sc-hero .elem13',{ y:-100 },'a') 
    .from(' .sc-hero .elem14',{ width : 0 },'a')
    .from('.sc-hero .elem07 .circle-pink-top',{ rotateZ: -180 },'a')
    .from('.sc-hero .circle-right',{ rotateZ: -180 },'a')
    .to('.sc-hero .elements-area .elem03',{ x : 0, opacity : 1,},'a')
    .to('.sc-hero .elements-area .elem05',{
        y : 0,
        opacity : 1,
    },'a')
    .to('.sc-hero .elements-area .dot-square',{
        scale3d :0,
        opacity : 1,
    },'a')

🔎 코드분석

  • gsap.from 타겟의 시작점에서 애니메이션 실행
    gsap.to 타겟의 끝점으로 애니메이션 실행
  • addlabel: 동시에 효과를 주기 위해 라벨링
  • .from('.header .inner',{ y: -30, opacity : 1, },'a') 헤더메뉴들은 위에서 나타나도록 구현
  • .from('.sc-hero .sub-tit, .sc-hero .btn-wrap',{ x: -170 },'a') hero영역의 텍스트들은 각각 왼쪽과 오른쪽에서 나타나도록 구현
  • .from('.sc-hero .elem04, .sc-hero .elem10, .sc-hero .elem12',{ scale:0 },'a') 점 모양의 도형들은 스케일로 사라졌다가 나타나게 조절
  • .from('.sc-hero .circle01.top, .sc-hero .circle01.btm',{ rotateZ: 180 },'a')돌아가며 채워지는 도형들은 rotate로 조절
  • .from('.sc-hero .hero-elem.elem02, .sc-hero .elem13',{ y:-100 },'a')조각상들은 y축을 이용해 위에서 아래로 나타나게끔 조절


2. Section 마다의 GSAP 스크롤 이벤트

📋 화면을 스크롤 하면 각각의 섹션마다 텍스트들과 도형들이 화면을 채우는 모션을 구현해 보았습니다.

◻️ SCRIPT

// sc-visit  
   scVisit = gsap.timeline({
       scrollTrigger:{
           trigger:".sc-visit",
           start:"0% 60%",
           end:"100% 0%",
       },
   })
        scVisit
       .to('.sc-visit .tit-visit',{
           x: 0, opacity : 1,
       })
       .to('.sc-visit .card-list > *',{
           y: 0, opacity :1 ,
           stagger:0.1
       })

   // sc-digital 
   scDigital = gsap.timeline({
       scrollTrigger:{
           trigger:".sc-digital",
           start:"0% 80%",
           end : "100% 0%",
           scrub : 1
       },
   })
       scDigital
       .addLabel('a')
       .to('.sc-digital .illustr-area img',{ scale : 1 },'a')
       .to('.sc-digital .border-area',{ opacity : 1, },'a')
       .to('.sc-digital .desc-wrap',{ x : 0, opacity : 1, },'a')
       .to('.sc-digital .tit-wrap .tit01, .sc-digital .tit-wrap .tit02, .sc-digital .tit-wrap .tit03',{ x : 0, opacity : 1, },'a')

   // Audio  
   scAudio = gsap.timeline({
       scrollTrigger:{
           trigger:".sc-audio",
           start:"0% 70%",
           end : "100% 0%",
       },

   })
       scAudio 
       .addLabel('a')
       .to('.sc-audio .group-tit > * ',{
           x : 0,
           opacity : 1
       },'a')

       .to('.sc-audio .audio-list > *',{
           y : 0,
           opacity : 1,
           stagger : 0.1,
          
       },'a')

   audioBtm = gsap.timeline({
       scrollTrigger:{
           trigger:".sc-audio",
           start:"50% 40%",
           end : "100% 0%",
       },
   })
    audioBtm
   .to('.sc-audio .group-more',{
       y : 0,
       opacity : 1,
   })
})

   // footer 
   footerMotion = gsap.timeline({
       scrollTrigger:{
           trigger:".footer",
           start:"0% 70%",
           end : "100% 100%",
           scrub : 1
       },
   })
       footerMotion
       .addLabel('a')
           .to('.footer .flex-area > * ',{
               y : 0,
               opacity : 1,
           },'a')
           .to('.footer .group-elements .elem01, .footer .group-elements .elem02, .footer .group-elements .elem03',{
               x : 0, y:0, z:0,
               opacity : 1,
           },'a')
           .from('.footer .footer-elem01',{
              rotateZ: 180,
           },'a')

🔎 코드분석

  • gsap.timeline gsap를 한꺼번에 묶어 순차적으로 실행하는 메서드
    이때 addLabel메서드도 함께 추가하여 사용해서 스크롤을 내리면 동시에 모션이 작동하게 끔 구현하였습니다.
  • scDigital 영역은 scrub을 이용해 스크롤을 위아래로 올리거나 내릴때마다 나타났다가 사라지는 모션을 주었습니다.


3. Click Event

1) Supscribe 모달창

📋 Sign-up 버튼이나 Trial 버튼 등 클릭시 Supscribe 모달창이 나오도록 클릭 이벤트를 이용해 구현하였습니다.

◻️ SCRIPT

    // modal 
    $('.modal').click(function(e){
        e.preventDefault();
        $('.sc-modal').addClass('on');
        $('body').addClass('hidden');
    })
    $('.sc-modal .btn-close, .sc-modal .bg-area').click(function(e){
        e.preventDefault();
        $('.sc-modal').removeClass('on');
        $('body').removeClass('hidden');
    })

2) 아코디언 메뉴

📋 화면이 줄여졌을 때, 햄버거 버튼 클릭시 나오는 아코디언 메뉴을 구현
메뉴 클릭시에 해당 요소 위치로 돌아가게끔 구현

◻️ HTML

 <div class="accodian-menu">
            <div class="inner">
                <button type="button" class="btn-close">
                    <span class="blind">닫기</span>
                </button>
                <nav class="gnb-area">
                    <a data-type="hero" class="btn-link underline">
                        VIRTUAL MUSEUM<i class="btn-link arrow-hover"></i>
                    </a>
                    <a data-type="visit" class="btn-link underline">
                        visit<i class="arrow-hover"></i>
                    </a>
                    <a data-type="hero" class="btn-link underline">
                        digital MUSEUM<i class="arrow-hover"></i>
                    </a>
                    <a data-type="audio" class="btn-link underline">
                        exhibition<i class="arrow-hover"></i>
                    </a>
                </nav>
                <div class="group-right">
                    <a href="" class="login modal underline" role="button">login</a>
                    <a href="" class="btn modal" role="button">sign up</a>
                </div>
            </div>
        </div>

◻️ SCRIPT

  $('.accodian-menu .gnb-area a').click(function(e){
        e.preventDefault();

        $('.accodian-menu, .accodian-menu .btn-close').removeClass('on');
        $('.header .btn-hamburger').removeClass('off');
        $('body').removeClass('hidden');

        type=$(this).data('type');
        sec_top = $('.sc-'+type).offset().top;
        // console.log(sec_top);
        $('html,body').animate({scrollTop:sec_top}, 300);
    })

🔎 코드분석

  • html

    자바스크립트에서 쓰일 변수설정에서 data를 이어주기 위해 section class의 name을 보고 각각에 해당하는 data-type 입력
    ex) a data-type="hero"

  • javascript
  1. type=$(this).data('type'); 메뉴 클릭시 아코디언메뉴 창이 닫히고 this (내가 선택한 링크메뉴) 를 통해 data type 지정
  2. sec_top = $('.sc-'+type).offset().top; section의 탑 위치 변수설정
  3. console.log(sec_top); 콘솔로 위치가 잘 잡혀여 있는 지 확인
  4. $('html,body').animate({scrollTop:sec_top}, 300); :animate 메서드를 이용하여 0.3초 동안 특정 요소의 위치로 이동하도록 구현


4. 구독 클릭시 나타나는 알림창

◻️ HTML

<div class="subscribe-wrap">
  <p class="intro">MMCA 뉴스레터 구독 신청 </p>
  <form action="" method="get">
    <fieldset>
      <legend class="blind">e-mail</legend>
      <div class="wrap">
        <input type="email" placeholder="E-MAIL" required>
      </div>
      <button type="submit" class="btn checked" aria-label="전송">
        <i class="footer-checked"></i>
      </button>
    </fieldset>
  </form>
</div>

🔎 코드분석

  • form 태그 에서 양식을 기입하여 버튼 클릭시 전송하기 때문에 button type="submit" 입력
  • aria-label은 버튼 안의 모든 텍스트 콘텐츠를 재정의하므로 '전송' 버튼이라 칭하였고 스크린 리더를 사용하는 모든 사람에게 작업을 명확하게 설명할 수 있습니다.


5.반응형 구현 (media Query)

📋 미디어쿼리를 통해 화면의 사이즈마다 맞는 레이아웃으로 구현해주었습니다.
화면 사이즈는 아래와 같이 3가지 기준으로 잡았습니다.

  • pc: 최대 1280px / 최소 1025px
  • 노트북/태블릿 가로버전: 최대 1024px / 최소 768px
  • 태블릿: 최대 767px / 최소기준 481px
  • 모바일: 최대 480px / 최소기준 320px

레이아웃 잡을 때는 각 화면의 최소기준을 보고 진행하였습니다.

@media screen and (max-width: 1280px) {}
@media screen and (max-width: 1024px) {}
@media screen and (max-width: 767px) {} 
@media screen and (max-width: 480px){}
profile
Web Publisher

0개의 댓글