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

[개인 프로필 사이트] 6. 포트폴리오 페이지 기능 구현

by DevJaewoo 2021. 6. 15.
반응형

Intro

이전 포스트에선 각 영역의 구조만 잡았다.

이제 추가/수정해야 할 사항은 다음과 같다.

  1. 배경 이미지 로딩 속도로 인한 화면 잘림
  2. 메뉴 클릭 시 해당 영역으로 이동
  3. 보고있는 영역에 해당하는 메뉴 강조
  4. 기술 막대 애니메이션
  5. 프로젝트 탭 변경 시 관련된 프로젝트만 보여주기

 

모든 코드는 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


배경 로딩 속도로 인한 잘림 현상

이미지의 용량이 너무 크다 보니 다음과 같이 로딩 중에 이미지가 잘려서 로딩된다.

이미지 크기 때문에 로딩 시 잘리는 모습

웹사이트에 들어왔을 때 이미지가 잘려있으면 보기 흉하기 때문에, 이미지가 로딩되는 과정을 보지 못하도록 로딩될 때 까지 화면을 가려주고, 서서히 밝아지며 보여지도록 페이지를 수정했다.

 

추가한 코드는 다음과 같다.

 

index.html

<div id="screen-block"></div>

<div id="preload">
	<img src="images/background4.jpg" onload="disableScreenBlock();">
</div>

 

style.css

#screen-block {
    position: fixed;
    width: 100%;
    height: 100%;
    background-color: black;
    z-index: 999;
    opacity: 1;
    visibility: visible;
    transition: all 4s;
}

#screen-block.hide {
    opacity: 0;
    visibility: hidden;
}

#preload {
    display: none;
}

 

index.js

function disableScreenBlock() {

	var pos = $(window).scrollTop();

	console.log("disableScreenBlock");

	if(pos == 0) {
		$("#screen-block").addClass("hide");
	}
	else {
		$("#screen-block").css({"display": "none"});
	}
}

 

화면을 가린 후 HTML에 보이지 않는 img 태그를 추가하여 이를 로딩하도록 한 뒤, 로딩이 완료되면 screen block을 숨겨 사용자로 하여금 이미지가 로딩되는 과정을 보지 못하게 하는 코드이다.

 

적용 후 결과는 다음과 같다.

적용 후 결과


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

메뉴의 각 항목 클릭 시 해당 영역으로 이동하는 코드를 추가해야 한다.

우선 메뉴의 각 항목에 page-link 클래스와 이동할 영역에 해당하는 속성을 부여해준다.

<nav class="flex">
    <div class="flex row menu wrapper">
        <div class="menu-item page-link active" dest="home">HOME</div>
        <div class="menu-item page-link" dest="about">ABOUT</div>
        <div class="menu-item page-link" dest="strength">STRENGTH</div>
        <div class="menu-item page-link" dest="projects">PROJECTS</div>
        <div class="menu-item page-link" dest="contact">CONTACT</div>
    </div>
</nav>

 

다음으로 page-link 클래스를 클릭했을 때 화면을 해당 위치로 이동시켜주는 Javascript 코드를 작성한다.

$(".page-link").on("click", function () {
	var anchor = $(this).attr("dest");
	$("html, body").animate({scrollTop: $("#" + anchor).offset().top}, 500);
});

 

적용 후 결과는 다음과 같다.

해시 URL 적용 결과


보고있는 영역에 해당하는 메뉴 강조

화면 스크롤 시 현재 영역에 해당하는 메뉴를 강조해주는 코드를 추가해야 한다.

우선 메뉴 항목에 active 클래스가 추가되었을 때 강조되도록 CSS 코드를 추가한다.

nav .menu-item.active {
    color: rgb(213, 118, 61);
}

 

다음으로 스크롤 시 현재 위치를 각 영역의 위치와 비교하여 메뉴에 active 클래스를 추가해주는 코드를 작성한다.

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

	// Link Highlighting
	if (pos2 >= $("#home").offset().top) {
		highlightLink("home");
	}

	if (pos2 >= $("#about").offset().top) {
		highlightLink("about");
	}

	if (pos2 >= $("#strength").offset().top) {
		highlightLink("strength");
	}

	if (pos2 >= $("#projects").offset().top) {
		highlightLink("projects");
	}

	if (pos2 >= $("#contact").offset().top
		|| pos2 >= $(document).height() - $(window).height() - 70) {
		highlightLink("contact");
	}
});

function highlightLink(anchor) {
	$("nav .active").removeClass("active");
	$("nav").find("[dest='" + anchor + "']").addClass("active");
}

 

적용 후 다음과 같이 화면을 내림에 따라 강조된 메뉴가 바뀌는 것을 볼 수 있다.

메뉴 강조 적용 결과


기술 막대 애니메이션

스크롤이 기술 위치까지 내려오면 정해진 크기까지 막대를 확장시켜주는 코드를 추가해야 한다.

기존엔 width를 직접 %로 지정해주는 형태였는데, 이를 max-width로 변경한다.

<div class="flex skills">
    <div class="skills-item">
        <div class="flex skills-text">C</div>
        <div class="bar-wrap">
            <div class="bar" style="max-width: 80%;"></div>
        </div>
    </div>
    <div class="skills-item">
        <div class="flex skills-text">C#</div>
        <div class="bar-wrap">
            <div class="bar" style="max-width: 70%;"></div>
        </div>
    </div>
    <div class="skills-item">
        <div class="flex skills-text">Kotlin</div>
        <div class="bar-wrap">
            <div class="bar" style="max-width: 60%;"></div>
        </div>
    </div>
    <div class="skills-item">
        <div class="flex skills-text">Java</div>
        <div class="bar-wrap">
            <div class="bar" style="max-width: 50%;"></div>
        </div>
    </div>
    <div class="skills-item">
        <div class="flex skills-text">Python</div>
        <div class="bar-wrap">
            <div class="bar" style="max-width: 60%;"></div>
        </div>
    </div>
    <div class="skills-item">
        <div class="flex skills-text">HTML</div>
        <div class="bar-wrap">
            <div class="bar" style="max-width: 50%;"></div>
        </div>
    </div>
    <div class="skills-item">
        <div class="flex skills-text">CSS</div>
        <div class="bar-wrap">
            <div class="bar" style="max-width: 40%;"></div>
        </div>
    </div>
    <div class="skills-item">
        <div class="flex skills-text">Git</div>
        <div class="bar-wrap">
            <div class="bar" style="max-width: 40%;"></div>
        </div>
    </div>
</div>

 

초기 width를 0으로 설정하고, 부모에 animated 클래스가 추가되면 width를 100%로 설정하도록 변경한다.

.bar {
    position: absolute;
    left: 0;
    top: 0;
    width: 0px;
    height: 100%;
    background: linear-gradient(to right, rgb(40, 0, 150), rgb(128, 0, 200));
    border-radius: 1em;
    transition: all 1s ease-in-out;
}

.skills.animated .bar {
    width: 100%;
}

 

각 막대들이 이전 막대보다 0.2초씩 늦게 나오도록 딜레이를 주고, 비율에 따라 애니메이션의 총 시간을 늘려준다.

위의 메뉴 강조 기능을 추가할 때 작성했던 onScroll 함수에 animated 클래스를 부여하는 코드를 추가한다.

$(document).ready(function () {

	var bars = document.getElementsByClassName("bar");

	for (var i = 0; i < bars.length; i++) {
		var max = parseFloat(bars[i].style.maxWidth) / 100;
		bars[i].style.transitionDelay = i * 0.2 + "s";
		bars[i].style.transitionDuration = (1 / max) + "s";
	}
});

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

	if (pos >= $(".skills").offset().top - 700) {
		$(".skills").addClass("animated");
	}
}

 

적용 후 해당 영역에 진입했을 때 애니메이션이 제대로 나오는것을 확인할 수 있다.

기술 막대 애니메이션 적용 결과

 

프로젝트 탭 변경 시 관련된 프로젝트만 보여주기

프로젝트 영역의 All/Personal/Business 탭을 변경할 때 변경한 탭에 속하는 프로젝트만 보여줘야 한다.

각 프로젝트에 all과 해당 프로젝트가 속하는 클래스(personal/business)를 부여한다.

<div class="projects-item all personal">
<div class="projects-item all business">

hide 클래스가 부여되었을 때 숨겨지도록 CSS를 작성한다.

.projects-item {
    position: relative;
    width: 350px;
    height: 350px;

    margin: 5px;

    background-color: #FFFFFF;
    opacity: 1;
    transition: height 1s, opacity 1s;
}

.projects-item.hide {
    margin: 0;
    width: 0px;
    height: 0px;
    opacity: 0;
}

탭이 클릭되었을 때 해당 탭과 같은 클래스를 가진 프로젝트만 띄워주는 Javascript 코드를 작성한다.

$(".projects-type").on("click", function () {

	$(".projects-type.active").removeClass("active");
	$(this).addClass("active");

	var type = $(this)[0].classList[2];
	var all = $(".projects-item");
	var on = $(".projects-item." + type);
	var off = all.not(on);

	console.log("type: " + type + " on: " + on.length + " off: " + off.length);

	on.removeClass("hide");
	off.addClass("hide");
});

 

적용 후 탭 변경 시 해당하는 프로젝트만 남는 것을 확인할 수 있다.

프로젝트 적용 결과

 

이렇게 포트폴리오 페이지가 완성되었다.

다음엔 취미 페이지를 만들 차례다.

반응형