genesystem

김종민·2024년 1월 16일
1

Portfolio

목록 보기
8/9
post-thumbnail

genesystem 클론코딩


🔎 작업내용

  • 사이트명: genesystem
  • 유형: 웹 (+모바일 작업 중), swiper, fullpage, 클론코딩
  • 특징: fullpage.js를 이용하여 섹션별로 스크롤과 네비게이션을 구현,
    .animate와 .css를 활용한 다양한 애니메이션 효과 구현

fullpage.js

스크롤 시 섹션별로 한 페이지씩 넘어가도록 구현하고 싶어서, 구글링을 해보니
fullpage.js라는 라이브러리가 있어서 활용해보았다.
기존에 정리 해둔 '🔗fullpage.js 정리'를 참고!

❗ 주의해야할 점 ❗

  • jquery를 사용한다고 하면 우선 jquery가 fullpage 스크립트보다 상위에 있어야 문제 없이 읽힌다!
  • 2.9 버전 위로는 유료 프로그램이라 상위버전은 개인용도로 밖에 사용하지 못하는걸로 알고있다. ( 본인은 일단 최신버전을 사용함🤓 )
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script> 👈 우선
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/4.0.20/fullpage.min.js" integrity="sha512-LGiXf+jHGTHcIybSsOWO3I/in+OObCkcEsWIZ7IyhzfD6RzD5qDUw2CK+JveuI7zTSEcDG//bIOvOpAJW2BWsg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

📝기본설정

  • section 태그의 클래스명에 section을 추가해주어야 하며, 그 section을 포합하고 있는 부모태그에게 #fullpage id값을 지정해준다.
  • 다양한 옵션들이 있지만 접근성을 위한 옵션들을 제외하곤 따로 사용하진 않았다.
$(document).ready(function() {
	$('#fullpage').fullpage({
		//options here
        keyboardScrolling: true, //접근성
        animateAnchor: true, //접근성
        recordHistory: true, //접근성
        autoHeight: true, //높이 자동설정
	});
	//methods
	$.fn.fullpage.setAllowScrolling(false); 👈
});

$.fn.fullpage.setAllowScrolling(false);는 전체 페이지의 스크롤을 허용하지 않도록 설정하는 메서드, 이 설정을 사용하면 사용자가 마우스 휠이나 터치 제스처 등을 통해 페이지를 스크롤하는 것을 방지할 수 있다.

📝네비게이션 설정

네이게이션을 설정해주기 위한 코드로 new fullpage#fullpage로 새롭게 정의해준다.

new fullpage('#fullpage', {
    anchors: ['section1', 'section2', 'section3', 'section4', 'section5', 'section6'], 1️⃣
    navigation: true,
    //navigationPosition: 'right', 2️⃣
});
  1. 네비게이션에서 표시하고자 하는 링크(anchor)를 정의해주는데, section1~6 처럼 기입하는게 디폴트지만 본인이 지정한 anchor 값인 data-anchor="slide1"를 넣어주어도 무방하다.
  2. 굳이 난 적용하진 않았지만 네비게이션의 위치를 정해줄 수 있는 옵션이다.

✅ 네비게이션 이벤트

종류

기본 네비게이션 설정에서 👈표시한 이벤트 옵션을 사용하였다.

onLeave // 사용자가 현재 섹션을 떠나기 시작할 때. 👈
afterLoad // 사용자가 섹션을 완전히 떠났을 때, 새로운 섹션에 도달했을 때.👈
afterRender // 호출 시점: fullPage.js가 초기화되고 페이지가 완전히 로드된 후.👈
afterResize // 호출 시점: 브라우저 창 크기 조정 후.
afterReBuild // 호출 시점: fullPage.js가 다시 빌드된 후.
afterResponsive // 호출 시점: 반응형 모드가 변경된 후.
afterSlideLoad // 호출 시점: 수평 슬라이드 섹션 내에서 슬라이드가 로드된 후.
onSlideLeave // 호출 시점: 수평 슬라이드 섹션 내에서 슬라이드를 떠나기 시작할 때.

이벤트 적용

new fullpage('#fullpage', {
        anchors: ['section1', 'section2', 'section3', 'section4', 'section5', 'section6'],
    navigation: true,
    responsiveWidth: 1025, 4️⃣
    keyboardScrolling: true,
    animateAnchor: true,
    recordHistory: true,
    autoHeight: true,

    afterRender: function () {
        var fpNav = document.querySelector('#fp-nav');

        // 앞에 추가 1️⃣
        if (fpNav) { 
            fpNav.insertAdjacentHTML('afterbegin', '<div class="changeNum"><span>01</span></div>');
        }

        // 뒤에 추가
        if (fpNav) { 1️⃣
            fpNav.insertAdjacentHTML('beforeend', '<div class="fixNum"><span>06</span></div>');
        }
    },
    onLeave: function(origin, destination, direction){
        let currentIndex = destination.index + 1; 

        updatePageIndex(currentIndex); 2️⃣

        // 현재 섹션이 마지막 섹션인 경우 #fp-nav 숨기기 3️⃣
        if (currentIndex === 7) {  
            $('#fp-nav, .header').hide();
            $('.sc-stage .up-btn').fadeIn(1000);
        } else {
            $('#fp-nav, .header').fadeIn();
            $('.sc-stage .up-btn').fadeOut();
        }
    },
});

// 페이지 인덱스를 업데이트하는 함수
function updatePageIndex(index) { 2️⃣
    var pageIndexElement = document.querySelector('#fp-nav .changeNum span');
    if (pageIndexElement) {
        pageIndexElement.textContent = ('0' + index).slice(-2); // 두 자리 숫자로 표시하도록 포맷팅
    }
}

  1. afterRender로 네비게이션인 #fpNav 앞에 chaneNum(스크롤 시 바뀌는 숫자)과 fixNum(전체 페이지 숫자)을 넣어주기 위함이다.
  • insertAdjacentHTML는 DOM(Document Object Model)에서 사용되는 메서드 중 하나로, 특정 요소의 특정 위치에 HTML 문자열을 삽입하는 역할을 한다.

    element.insertAdjacentHTML(position, text);

"beforebegin": element 바로 앞에 삽입합니다.
"afterbegin": element의 첫 번째 자식 요소로 삽입합니다.
"beforeend": element의 마지막 자식 요소로 삽입합니다.
"afterend": element 바로 뒤에 삽입합니다.
  • fpNav.insertAdjacentHTML('afterbegin', '<div class="changeNum"><span>01</span></div>');
    : afterbegin은 fpNav의 자식 요소들의 가장 앞부분에 새로운 HTML 코드를 삽입하는 메서드, 여기서는 'changeNum'이라는 클래스를 가진 div를 생성하고 그 안에 '01'이라는 텍스트를 가진 span을 넣어주었다.

  • fpNav.insertAdjacentHTML('beforeend', '<div class="fixNum"><span>06</span></div>');
    : beforeend는 fpNav의 자식 요소들의 가장 뒷부분에 새로운 HTML 코드를 삽입하는 메서드, 여기서는 'fixNum'이라는 클래스를 가진 div를 생성하고 그 안에 '06'이라는 텍스트를 가진 span을 넣어주었다.


  1. onLeave로 섹션을 떠나기 시작할 때 위에서 선언해준 chageNum의 숫자, 즉 바뀔 섹션의 숫자로 바꿔주기 위함이다.
  • updatePageIndex(index) 함수는 pageIndexElement에 1번에서 넣어준 changeNum을 불러오는 변수를 선언해주고, 조건문을 이용해서 pageIndexElement.textContent라는 새로운 텍스트를 넣어주는 메서드를 사용, ('0' + index)로 표기하여 두 자리 숫자로 나타나게 해주었고, .slice라는 배열을 만들어내는 메서드를 사용해 2번째부터 나열되도록 설정하였다.

    🙌잠깐🙌 .slice 메서드 정리
    slice 메서드는 배열이나 문자열에서 일부분을 추출하여 새로운 배열이나 문자열을 만드는 데 사용됩니다. slice 메서드는 시작 인덱스와 종료 인덱스를 기준으로 원본의 일부를 추출합니다.

    배열의 경우

    const originalArray = [1, 2, 3, 4, 5];
    const newArray = originalArray.slice(1, 4); 
    console.log(newArray); // [2, 3, 4]
    

    문자열의 경우

    const originalString = "Hello, World!";
    const newString = originalString.slice(0, 5);
    console.log(newString); // "Hello"
    

    음수를 사용 할 경우

    const originalArray = [1, 2, 3, 4, 5];
    const newArray = originalArray.slice(-3);
    console.log(newArray); // [3, 4, 5]
    

  1. 해당 위치에 다다랐을 때 네비게이션이 사라졌다, 나타났다 하게 하기 위함이다.
  • let currentIndex = destination.index + 1; ( 목적지,도착지 라는 뜻을 가진 destination ) 으로 다음 섹션의 인덱스값에 +1를 해준다.
  • updatePageIndex(index) 함수에 index 값에 currentIndex변수를 넣어서 해당 위치의 인덱스 값을 넣어준다.
  • 조건문을 사용해서 (currentIndex === 7) 즉 footer 섹션에 다다랐을 때 숨고
    벗어나면 나타나도록 설정하였다.
  1. 브라우저의 너비가 1024px 이하로 줄어들면 fullPage.js 플러그인이 자동으로 해제되어 원래의 페이지 스크롤 동작으로 돌아갑니다. 이는 미디어 쿼리처럼 반응형 디자인을 구현하고자 할 때 유용하다.

✅ fullpage 팝업창의 body 스크롤 막기

fullpage.js를 사용할 경우 팝업창/사이드 메뉴 출연 시 body의 스크롤이 기존처럼 overflow:hidden으로 통제가 되지가 않아서 찾아보고 해결책을 찾았다!

$('.finder .top-btn').click(function(e){
    e.preventDefault();
    let finder = $('.finder');
    let body = $('body');

    if (finder.hasClass('on')) {
        body.removeClass('hidden'); 1️⃣
        body.off('scroll.hidden touchmove.hidden mousewheel.hidden'); 2️⃣
        finder.removeClass('on');
    } else {
        body.addClass('hidden'); 1️⃣
        body.on('scroll.hidden touchmove.hidden mousewheel.hidden', function(e) { 2️⃣
            e.preventDefault(); 3️⃣
            e.stopPropagation(); 3️⃣
            return false;
        });
        finder.addClass('on');
    }
});
  1. 기존과 같이 body에 hidden 클래스를 추가하거나 삭제하는 코드를 넣어준다.
  2. .off / on('scroll.hidden touchmove.hidden mousewheel.hidden');는 이벤트 핸들러를 제거/추가하는 코드입니다. body에 대해 이벤트 핸들러가 등록되어 있고, scroll.hidden, touchmove.hidden, mousewheel.hidden 이벤트에 대해 이벤트 핸들러가 실행되는데, 이 코드는 해당 이벤트 핸들러를 제거/추가합니다.
  3. e.preventDefault()e.stopPropagation()을 호출하고 return false;를 반환하고 있습니다. 이것은 주로 스크롤이나 터치 무브 등의 동작을 막아서 해당 이벤트가 상위 요소로 전파되지 않도록 하는 용도로 사용됩니다.


.animate / .css

.animate

header에 hover될 때 아래의 gnb의 공간이 확장되며, 하단의 리스트도 fadeIn되도록 하였다.

$('.header-inner').hover(
    function(){
        let gnbItem = $('.gnb .item');
        let gnbLi = $('.gnb .sub-list');

        $(gnbItem).stop().animate({
            padding: '2vw 4rem'
        }, 'slow');

        $(gnbLi).stop().fadeIn(1000);
    },
    function(){
        let gnbItem = $('.gnb .item');
        let gnbLi = $('.gnb .sub-list');
        let hideLi = $('.gnb .sub-item .dep-list, .icon');

        $(gnbItem).stop().animate({
            padding: '1rem 2rem'
        }, 'slow');
        $(gnbLi).stop().hide();

        $(hideLi).removeClass('on');
    }
);

.css

온로드 될 때 상위의 섹션의 백그라운드 이미지가 크기가 커지게 하고 싶었는데,
.animate() 함수는 기본적으로 백그라운드 이미지의 크기를 변경하는 데에는 사용되지 않다는걸 알게되어 대신에 .css를 사용, scale() 함수 대신 scaleX()와 scaleY()를 사용하여 요소의 크기를 변경하였다.

window.onload = function() {
    $('.sc-visual .title').addClass('on');
    $('.sc-visual .visual-bg').css({
        transform: 'scaleX(1.1) scaleY(1.1)'
    })
};
profile
웹 퍼블리셔의 코딩 일기

0개의 댓글