Javascript 구현해야지..구현해야지..생각만 하다 드디어 구현했다.
저번주에 구현해 낸 것은 아래와 같다.
1. 메인 타이틀 타자기 효과
2. 타이틀 온로드 되면 아래에서 위로 글자 올라오게 하기
3. mouseover시 이미지 줌 인
4. work 페이지에 "자세히 알아보기" 팝업창
우선, Preview 부터 보고 갑시다.
let mainTitle = document.getElementById("main-title");
const content = "Glad to Meet You."
let index = 0;;
// content의 글자가 하나씩 늘어나게 - index로
function typing() {
let text = `${content[index++]}`;
if (index <= content.length) {
mainTitle.textContent += text;
}
}
function start(){
setInterval(typing, 100);
}
알파벳 하나 하나를 index 숫자가 늘어남에 따라 메인 페이지에 추가되도록 했다.
if
문을 사용하여 문구 길이를 초과할 때까지 글자가 하나씩 늘어나도록 했고, 딱 1회만 움직이도록 하기 위해 index가 문구 길이에 도달하면 다른 action을 취하지 않도록 뒀다.
글자는 100ms마다 1글자씩 늘어나도록 하기 위해 setInterval함수를 사용하여 천천히 추가되도록 하였다.
#main-title::after {
content: "";
position: absolute; /*main-title따라 움직이도록*/
width: 1px;
height: 80%;
border-right: 8px solid #4834d4;
animation : blink 0.5s infinite ease;
}
@keyframes blink { /* after에 애니메이션 effect */
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
css의 가상 클래스인 :after
를 사용하여 글자 뒤마다 자판 위치를 나타내는 바를 만들어주었다.
:after
를 사용해서 글자가 늘어날때마다 자동적으로 맨 끝에 붙게 된다.
또한 애니메이션을 사용하여 깜빡깜빡하는(?) 효과를 주었다(정확히 뭐라고 지칭하는지를 모르겠다..커서가 깜빡깜빡하는 상태...ㅠㅠ).
CSS
.main-letter {
position: relative;
top: -40%;
left: 20%;
opacity: 0;
transition: all 700ms ease-in-out;
}
.letter-up {
top: -60%;
opacity: 1;
}
Javascript
window.onload = function() {
mainLetter.classList.add("letter-up");
}
letter-up
이라는 클래스를 별도로 만들어 메인 타이틀이 움직일 위치값 및 opacity를 지정해줬다.
main-letter
에 transition
을 주어 부드럽게 위치가 변하도록 했다.
화면이 모두 로딩이 완료된 다음에 타이틀이 움직여주었으면 해서 자바스크립트로 onload
를 설정했고, 이후 classList
에 letter-up
이 추가되도록 해 움직일 수 있도록 했다.
HTML
<div class="work">
<div class="work-cover">
<a href="./works.html" id="workimg" class="work-img interactive"></a>
</div>
<a href="./works.html">interactive web practice</a>
</div>
CSS
.work-cover { /* cover씌워서 css로 이미지 scale 처리 */
width: 370px;
height: 230px;
overflow: hidden;
background-color: #000;
}
.work-img {
display: block;
width: 100%;
height: 100%;
transition: all 400ms ease-out;
}
.work-img:hover {
transform: scale(1.15);
opacity: 0.7;
}
work-img
를 감싸도록 work-cover
를 생성하여 scale처리가 가능하도록 했다.
work-cover
에 원하는 이미지 사이즈를 주고, work-img
는 work-cover
의 사이즈를 따라가도록 가로, 세로를 모두 100%로 주었다.
work-cover
의 bgc를 black으로 처리하여 work-img
에 opacity
가 발생하면 화면이 어두워지도록 처리했다.
역시 부드럽게 움직이도록 transition
을 주었다.
"자세히 알아보기"를 클릭하면 팝업이 뜨게 하고, ❌버튼을 누르면 팝업이 사라질 수 있도록 class가 지워졌다 생겼다 하도록 구현했다.
// 팝업창 열기
function openPopup(id){
let popup = document.getElementById(`${id}`);
popup.classList.remove("disappear");
}
// 팝업창 닫기
function closePopup(id){
let popup = document.getElementById(`${id}`);
popup.classList.add("disappear");
}
HTML
에 미리 각 파트마다 id
를 부여하여 5개중 특정한 1개가 선택할 수 있도록 하였다.
disappear
이라는 class를 더하면 css에서 display: none
이 되도록 설정했다.
appear보다 disappear
쪽이 css에서 처리할 글자 수가 적기에 보다 심플할 것 같아서 disappear
로 진행하기로 선택했다.
function popupID() {
interBtn.addEventListener("click", () => {
clickNum = interBtn.dataset.indexNumber;
openPopup(clickNum);
});
}
function shutPopup() {
interExit.addEventListener("click", (event) => {
shutID = event.target.parentNode.parentNode.parentNode.id;
closePopup(shutID);
})
}
팝업창을 닫을 때는 ❌ 버튼을 눌러야만 꺼지도록 만들기 위해 sutPopup()
이라는 별도의 함수를 생성하였다.
열고 닫을 놈의 id를 찾아내는 과정을 각각의 버튼을 각각 따로따로 누를 때마다 실행되도록 설정해놨는데, 다 만들고 보니 너무 지저분한것 같다.
id도 있는 마당에 하나의 동작으로 5개를 구분지을 수 있을 것 같은데 이상하게도 공통된 class를 부여하면 맨 위의 div
에만 작동된다(다른 곳에는 전혀 반영안됨).
어쩔 수 없이 아래와 같이 무식하게(?) 만들었는데 어떻게 5개의 div
를 하나의 class만을 사용해 모두 컨트롤 할 수 있을지 고민해보아야 겠다.
function popupID() {
interBtn.addEventListener("click", () => {
clickNum = interBtn.dataset.indexNumber;
openPopup(clickNum);
});
brunchBtn.addEventListener("click", () => {
clickNum =brunchBtn.dataset.indexNumber;
openPopup(clickNum);
});
carrotBtn.addEventListener("click", () => {
clickNum = carrotBtn.dataset.indexNumber;
openPopup(clickNum);
});
momentumBtn.addEventListener("click", () => {
clickNum = momentumBtn.dataset.indexNumber;
openPopup(clickNum);
});
habitBtn.addEventListener("click", () => {
clickNum = habitBtn.dataset.indexNumber;
openPopup(clickNum);
});
}
어떻게 구현 하시는지 구경하는 재미👍
항상 많이 배우고 가요✨