본문 바로가기
Projects/개인 프로필 사이트

[개인 프로필 사이트] 7. 취미 페이지 작성 및 기능 구현

by DevJaewoo 2021. 6. 15.
반응형

Intro

하위 3개 페이지 중 2번째 페이지인 취미 페이지를 작성할 차례이다.

내가 해본 게임들을 카테고리별로 나눠서 나열하였다.

담는 내용이 그리 많지 않은 만큼 UI도 단순하다.

 

완성된 UI는 다음과 같다.

취미 페이지 상단
취미 페이지 중단

 

모든 코드는 github에 업로드해두었습니다.

아래의 링크를 클릭하여 소스코드를 보실 수 있습니다.

https://github.com/DevJaewoo/DevJaewoo.github.io

 

DevJaewoo/DevJaewoo.github.io

Contribute to DevJaewoo/DevJaewoo.github.io development by creating an account on GitHub.

github.com


취미 페이지 기능 구현

페이지를 만들며 추가/수정한 사항이다.

  1. 게임 이미지를 유튜브 썸네일로 교체
  2. 화면에 표시되고 있는 게임 이미지만 로딩
  3. 게임 리스트 이동
  4. 메뉴 클릭 시 해당 영역으로 이동
  5. 메뉴 스크롤 시 화면 우측에 고정
  6. 보고 있는 화면 메뉴 강조 및 카테고리와 같은 색 설정

게임 이미지 유튜브 썸네일로 교체

단순히 게임 이미지 하나만 넣기엔 너무 페이지가 심심해서 여러 이미지를 번갈아가며 보여주도록 하는 방법을 찾던 중 유튜브에서 영상마다 4개의 썸네일을 제공한다는 정보를 얻게 되어 적용시켰다.

자세한 정보는 추후에 포스팅하도록 하겠다.

 

모든 이미지를 2초 주기로 4개의 썸네일을 번갈아가며 출력하도록 코드를 작성했다.

var imgType = ["/maxresdefault.jpg", "/maxres1.jpg", "/maxres2.jpg", "/maxres3.jpg"];
var imgIndex = 0;
var currentImg;

function updateImage() {
    var img = $(".category-item img");
    var currentElement;

    currentImg = imgType[imgIndex];
    imgIndex = (imgIndex + 1) % 4;
    
    for(var i=0; i<$(img).length; i++)
    {
        currentElement = $(img).eq(i);
        currentElement.attr("src", "https://img.youtube.com/vi/" + currentElement.attr("vid") + currentImg);
    }
}

updateImage(true);
setInterval(updateImage, 2000);

화면에 표시되고 있는 게임 이미지만 로딩

2초 주기로 20개가 넘는 이미지를 계속 새로고침 하니 웹사이트가 새로고침 주기마다 약간의 딜레이가 걸리는 문제가 생겼다.

이를 해결하기 위해 현재 화면에 표시되고 있는 이미지만 로딩되도록 조건문을 추가했다.

처음 1번에 한해 전체를 새로고침 하고, 그 뒤 2초마다 화면에 있는 이미지만 새로고침 한다.

 

var imgType = ["/maxresdefault.jpg", "/maxres1.jpg", "/maxres2.jpg", "/maxres3.jpg"];
var imgIndex = 0;
var currentImg;

function updateImage(refreshAll = false) {
    var img = $(".category-item img");
    var elementTop;
    var elementBottom;
    var viewportTop;
    var viewportBottom;
    var isInViewport;

    var currentElement;

    currentImg = imgType[imgIndex];
    imgIndex = (imgIndex + 1) % 4;
    
    for(var i=0; i<$(img).length; i++)
    {
        currentElement = $(img).eq(i);

        elementTop = currentElement.offset().top;
        elementBottom = elementTop + currentElement.outerHeight();

        viewportTop = $(window).scrollTop();
        viewportBottom = viewportTop + $(window).height();

        isInViewport = elementBottom > viewportTop && elementTop < viewportBottom;

        if(isInViewport == false && refreshAll == false) continue;
        
        currentElement.attr("src", "https://img.youtube.com/vi/" + currentElement.attr("vid") + currentImg);
    }
}

updateImage(true);
setInterval(updateImage, 2000);

 

적용 후 이미지들이 계속 바뀌어가며 출력되는 것을 확인할 수 있다.

이미지 변경 기능 적용 결과


카테고리 숨기기

카테고리가 너무 많아서 각 카테고리 별로 숨기는 기능을 추가했다.

 

CSS

.category-container .category-info i::before {
    transition: all 0.4s;
}

.category-container.hide .category-info i::before {
    transform: rotate(-90deg);
}

 

Javascript

$(".category-info").on("click", function() {
    $(this).parent().toggleClass("hide");
    if($(this).parent().hasClass("hide")) {
        $(this).parent().css("height", "40px");
    }
    else {
        $(this).parent().css("height", "265px");
    }
});

 

적용 후 결과

카테고리 숨기기 적용 결과


게임 리스트 이동

이전의 이미지를 보면 알 수 있듯이 한 카테고리에 표시되는 이미지가 3개뿐이다.

포함되어 있는 이미지는 많지만 화면상에 다 표시하기엔 공간을 너무 많이 차지하기에 화면 크기에 따라 3개까지만 출력하였다.

출력되지 않은 이미지를 확인할 수 있도록 이전/다음 버튼을 추가하고, 구현하였다.

 

각 카테고리의 아래쪽에 다음 HTML 코드를 추가하였다.

<div class="category-move left">
	<i class="mdi mdi-chevron-left"></i>
</div>
<div class="category-move right">
	<i class="mdi mdi-chevron-right"></i>
</div>

 

CSS

.category-move {
    position: absolute;

    top: calc(calc(calc(100% - 40px) / 2) + 40px);
    transform: translateY(-50%);

    opacity: 1;
    transition: all 0.4s;
    transition-delay: 0.1s;

    cursor: pointer;
    z-index: 1;
}

.category-container.hide .category-move{
    opacity: 0;
    transition-delay: 0s;

    z-index: -1;
}

.category-move i {
    font-size: 50px;
    color: rgb(255, 64, 66);
}

.category-move i::before {
    
    /* border: 2px solid rgb(255, 64, 66); */
    border-radius: 15px;
    background: rgba(255, 255, 255, 0.6)
}

.category-move.left {
    left: 30px;
}

.category-move.right {
    right: 30px;
}

 

Javascript

$(".category-move.left").on("click", function() {
    var list = $(this).siblings(".category-list");

    var left = parseInt(list.css("left"));
    left += (left <= -400) ? 400 : -left;

    list.animate({left: (left + "px")});
});

$(".category-move.right").on("click", function() {
    var container = $(this).parent();
    var list = $(this).siblings(".category-list");

    var left = parseInt(list.css("left"));
    var len = list.width() - container.width() + left;

    if(len <= 0) return;

    left -= (len >= 400) ? 400 : len;
    list.animate({left: (left + "px")});
});

list, container, left, len의 관계

위와 같이 list와 container, left 값을 통해 len값을 알 수 있다.

 

left값은 부모(container)의 왼쪽 선을 기준으로 얼마나 오른쪽 방향으로 떨어져 있는지를 나타내는 값이기 때문에 위와 같이 왼쪽 방향으로 떨어져있는 경우 값이 음수가 된다.

 

왼쪽 버튼의 경우 오른쪽으로 이동시켜야 하므로 left값이 0인지 아닌지 판단하여 left 값을 증가시킨다.

오른쪽 버튼의 경우 왼쪽으로 이동시켜야 하므로 list의 남아있는 길이를 구하고 그 값이 0보다 큰지 판단하여 left값을 감소시킨다.

 

적용시킨 후 버튼을 클릭하면 리스트가 움직이는 것을 확인할 수 있다.


메뉴 클릭 시 해당 영역으로 이동

이전에 포스팅했던 포트폴리오 페이지의 메뉴와 거의 동일하다.

아래의 포스트에서 참고하여 작성하면 된다.

 

6. 포트폴리오 페이지 기능 구현

모든 코드는 github에 업로드 해두었습니다. 아래의 링크를 클릭하여 소스코드를 보실 수 있습니다. https://github.com/DevJaewoo/DevJaewoo.github.io DevJaewoo/DevJaewoo.github.io Contribute to DevJaewoo/D..

devjaewoo.tistory.com


메뉴 스크롤 시 화면 우측에 고정

이전의 포트폴리오 페이지와는 다르게 이번엔 메뉴를 우측에 고정시켜보았다.

스크롤 시 위치를 비교하여 fixed 클래스만 부여해주는 코드라 그리 복잡하지 않다.

 

CSS

#menu {
    position: absolute;
    top: 800px;
    right: 50px;
    
    padding: 30px;
    border: 3px solid rgb(255, 64, 66);
    border-radius: 15px;
    background: #FFFFFF;

    z-index: 999;
}

#menu.fixed {
    position: fixed;
    top: 50%;
    right: 50px;
    transform: translateY(-50%);
}

 

Javascript

$(window).on("scroll", function () {
	var pos = $(window).scrollTop();
	var pos2 = pos + 300;

    if(pos >= $("#adventure").offset().top) {
        $("#menu").addClass("fixed");
    }
    else {
        $("#menu").removeClass("fixed");
    }
});

 

적용 후 스크롤 시 메뉴가 따라오는 것을 확인할 수 있다.

메뉴 고정 결과


보고 있는 화면 메뉴 강조 및 카테고리와 같은 색 설정

이전 포스팅의 메뉴와 같은 방식이지만, 카테고리의 수가 12개나 되어 하나하나 if문으로 지정해주면 코드가 상당히 지저분해졌다.

각 카테고리를 string 배열에 넣어서 for문으로 판별하도록 코드를 구성했다.

클릭 시 해당 영역으로 이동시키기 위해 부여했던 dest 속성과 id 값이 같은 element의 색상 값을 가져와 적용시켰다.

 

Javascript

var category = ["adventure", "action", "rpg", "roguelike", "survive", "defense", 
                "multiplay", "sandbox", "strategy", "puzzle", "rhythm", "other"];

$(window).on("scroll", function () {
	var pos = $(window).scrollTop();
	var pos2 = pos + 300;

    if(pos >= $("#adventure").offset().top) {
        $("#menu").addClass("fixed");
    }
    else {
        $("#menu").removeClass("fixed");
    }

	// Link Highlighting
    for(var i=0; i<category.length; i++) {
        if(pos2 >= $("#" + category[i]).offset().top) {
            highlightLink(category[i]);
        }
    }
});

 

적용 후 색이 잘 변하는 것을 볼 수 있다.

현재 메뉴 색 강조 결과

 

이렇게 취미 페이지가 완성되었다.

다음은 피드백 페이지를 만들 차례다.

반응형