QUOTE THE DAY
“ 당신이 6개월 이상 한 번도 보지 않은 코드는 다른 사람이 다시 만드는 게 훨씬 더 나을 수 있다. ”
-
이글슨 (Eagleson)
반응형
게임 이펙트(Game Effect)란?
자바스크립트를 사용하여 구현된 게임에서의 이펙트는 일반적으로 다양한 애니메이션 기술과 그래픽 처리 기술을 사용하여 구현됩니다. 이를 통해 게임에 동적이고 생동감 있는 느낌을 부여할 수 있습니다.
''
선택자
const musicWrap = document.querySelector(".music__wrap");
const musicName = musicWrap.querySelector(".music__control .title h3");
const musicArtist = musicWrap.querySelector(".music__control .title p");
const musicView = musicWrap.querySelector(".music__view .image img");
const musicAudio = musicWrap.querySelector("#main-audio");
const musicPlay = musicWrap.querySelector("#control-play");
const musicPrevBtn = musicWrap.querySelector("#control-prev");
const musicNextBtn = musicWrap.querySelector("#control-next");
const musicProgress = musicWrap.querySelector(".progress");
const musicProgressBar = musicWrap.querySelector(".progress .bar");
const musicProgressBarCurrent = musicWrap.querySelector(".progress .timer .current");
const musicProgressBarDuration = musicWrap.querySelector(".progress .timer .duration");
음악 재생
window.addEventListener("load", () => {
loadMusic(musicIndex);
console.log(musicIndex);
});
let musicIndex = 2 //현재 음악 인덱스
const loadMusic = (num) => {
musicName.innerText = allMusic[num-1].name; //뮤직 이름
musicArtist.innerText = allMusic[num-1].artist; //뮤직 아티스트
musicView.src = `img/${allMusic[num-1].img}.png`; //뮤직 이미지
musicView.alt = allMusic[num-1].name; //뮤직 이미지 alt
musicAudio.src =`audio/${allMusic[num-1].audio}.mp3`; //뮤직 파일
}
- musicName.innerText: 음악의 이름을 나타내는 요소의 내부 텍스트를 변경합니다. innerText는 해당 요소의 내부 텍스트 값을 변경할 때 사용합니다. allMusic[num-1].name을 이용하여 num에 해당하는 인덱스의 뮤직 이름을 가져옵니다.
- musicArtist.innerText: 음악의 아티스트를 나타내는 요소의 내부 텍스트를 변경합니다. allMusic[num-1].artist를 이용하여 num에 해당하는 인덱스의 뮤직 아티스트를 가져옵니다.
- musicView.src: 음악 이미지 파일의 경로를 변경합니다. allMusic[num-1].img를 이용하여 num에 해당하는 인덱스의 뮤직 이미지 파일명을 가져옵니다. 그리고 img/와 .png를 붙여서 이미지 파일의 경로를 완성합니다.
- musicView.alt: 음악 이미지의 대체 텍스트를 변경합니다. allMusic[num-1].name을 이용하여 num에 해당하는 인덱스의 뮤직 이름을 가져옵니다.
- musicAudio.src: 음악 파일의 경로를 변경합니다. allMusic[num-1].audio를 이용하여 num에 해당하는 인덱스의 뮤직 파일명을 가져옵니다. 그리고 audio/와 .mp3를 붙여서 음악 파일의 경로를 완성합니다.
재생
const playMusic = () => {
musicWrap.classList.add("paused");
musicPlay.setAttribute("title", "정지");
musicPlay.setAttribute("class", "stop");
musicAudio.play();
}
- musicWrap.classList.add("paused"): musicWrap 요소에 paused 클래스를 추가합니다. paused 클래스는 CSS 스타일링을 통해 음악을 일시정지할 때 사용합니다.
- musicPlay.setAttribute("title", "정지"): musicPlay 요소의 title 속성 값을 "정지"로 변경합니다. title 속성은 해당 요소에 마우스를 올렸을 때 나타나는 툴팁의 내용을 나타냅니다.
- musicPlay.setAttribute("class", "stop"): musicPlay 요소의 class 속성 값을 "stop"으로 변경합니다. "stop" 클래스는 CSS 스타일링을 통해 정지 버튼을 나타낼 때 사용합니다.
- musicAudio.play(): musicAudio 요소의 play() 메서드를 호출하여 음악 파일을 재생합니다.
정지
const pauseMusic = () => {
musicWrap.classList.remove("paused");
musicPlay.setAttribute("title", "재생");
musicPlay.setAttribute("class", "play");
musicAudio.pause();
}
- musicWrap.classList.remove("paused"): musicWrap 요소에서 paused 클래스를 제거합니다. paused 클래스는 CSS 스타일링을 통해 음악을 일시정지할 때 사용합니다.
- musicPlay.setAttribute("title", "재생"): musicPlay 요소의 title 속성 값을 "재생"으로 변경합니다. title 속성은 해당 요소에 마우스를 올렸을 때 나타나는 툴팁의 내용을 나타냅니다.
- musicPlay.setAttribute("class", "play"): musicPlay 요소의 class 속성 값을 "play"으로 변경합니다. "play" 클래스는 CSS 스타일링을 통해 재생 버튼을 나타낼 때 사용합니다.
- musicAudio.pause(): musicAudio 요소의 pause() 메서드를 호출하여 음악 파일을 일시정지합니다.
이전곡 듣기
const prevMusic = () => {
// musicIndex--;
// if(musicIndex == 0)musicIndex = allMusic.length;
musicIndex == 1 ? musicIndex = allMusic.length : musicIndex--; //삼항연산자로 사용 가능
loadMusic(musicIndex);
playMusic();
}
- musicIndex == 1 ? musicIndex = allMusic.length : musicIndex--;: 삼항 연산자를 이용하여 musicIndex 값을 이전 값으로 변경합니다. 만약 musicIndex 값이 1이라면 musicIndex 값을 allMusic 배열의 마지막 인덱스 값으로 변경하고, 그렇지 않으면 musicIndex 값을 1 감소시킵니다. 이렇게 변경된 musicIndex 값을 loadMusic 함수에 전달하여 해당 음악 정보를 화면에 출력하고, playMusic 함수를 호출하여 음악을 재생합니다.
- loadMusic(musicIndex): musicIndex 값을 전달하여 해당 음악 정보를 loadMusic 함수를 통해 화면에 출력합니다.
- playMusic(): 이전 음악 정보가 출력된 후에는 playMusic 함수를 호출하여 음악을 자동으로 재생합니다.
다음곡 듣기
const nextMusic = () => {
// musicIndex++;
// if(musicIndex == allMusic.length+1)musicIndex = 1;
musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++; //삼항연산자로 사용 가능
loadMusic(musicIndex);
playMusic();
}
- musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++;: 삼항 연산자를 이용하여 musicIndex 값을 다음 값으로 변경합니다. 만약 musicIndex 값이 allMusic 배열의 마지막 인덱스와 동일하다면 musicIndex 값을 1로 변경하고, 그렇지 않으면 musicIndex 값을 1 증가시킵니다. 이렇게 변경된 musicIndex 값을 loadMusic 함수에 전달하여 해당 음악 정보를 화면에 출력하고, playMusic 함수를 호출하여 음악을 재생합니다.
- loadMusic(musicIndex): musicIndex 값을 전달하여 해당 음악 정보를 loadMusic 함수를 통해 화면에 출력합니다.
- playMusic(): 다음 음악 정보가 출력된 후에는 playMusic 함수를 호출하여 음악을 자동으로 재생합니다.
뮤직 진행바
//뮤직 진행바
musicAudio.addEventListener("timeupdate", e => {
console.log(e);
const currentTime = e.target.currentTime; //현재 재생되는 시간
const duration = e.target.duration; //오디오의 총 길이
let progressWidth = (currentTime/duration) * 100; //전체길이에서 현재 진행되는 시간을 백분위 단위로 나누는
musicProgressBar.style.width = `${progressWidth}%`;
//전체 시간
musicAudio.addEventListener("loadeddata", () => {
let audioDuration = musicAudio.duration;
let totalMin = Math.floor(audioDuration / 60);
let totalSec = Math.floor(audioDuration % 60);
if(totalSec < 10) totalSec = `0${totalSec}`;
musicProgressBarDuration.innerText = `${totalMin}:${totalSec}`;
});
//진행 시간
let currentMin = Math.floor(currentTime / 60);
let currentSec = Math.floor(currentTime % 60);
if(currentSec < 10) currentSec = `0${currentSec}`;
musicProgressBarCurrent.innerText = `${currentMin}:${currentSec}`;
});
- 현재 재생 중인 음악의 재생 시간인 currentTime과 총 길이인 duration을 구합니다. 그리고 currentTime을 duration으로 나눈 후 100을 곱해 현재 음악의 재생 진행 상태를 계산합니다.
- 계산된 값을 musicProgressBar의 스타일 속성 width에 적용하면, 뮤직 진행바의 길이가 현재 음악의 재생 진행 상태에 맞게 변경됩니다.
- loadeddata" 이벤트를 등록하여 뮤직 오디오가 로드되면, 오디오의 총 길이를 계산하여 musicProgressBarDuration 요소에 표시합니다.
- 현재 음악의 재생 시간인 currentMin과 currentSec를 구하여 musicProgressBarCurrent 요소에 표시합니다.
진행 버튼 클릭
//진행 버튼 클릭
musicProgress.addEventListener("click", (e) =>{
let progressWidth = musicProgress.clientWidth; //진행바 전체 길이
let clickOffsetX = e.offsetX; //진행바를 기준으로 측정되는 X좌표 값
let songDuration = musicAudio.duration; //오디오 전체 길이
//백분위로 나눈 숫자에 다시 전체 길이를 곱해서 현재 재생값으로 바꿈
musicAudio.currentTime = (clickOffsetX/progressWidth) * songDuration;
});
musicProgress 요소에 click 이벤트를 추가하여 클릭하면 실행되도록 합니다.
이벤트 핸들러 함수에서는 musicProgress 요소의 전체 길이(clientWidth)와 클릭한 지점의 X 좌표 값(e.offsetX)을 이용하여 클릭한 지점의 백분위(clickOffsetX/progressWidth)를 계산합니다.
이 값을 오디오의 총 길이(musicAudio.duration)에 곱하여 클릭한 지점에 해당하는 재생 시간으로 설정합니다.
이렇게 하면 사용자가 원하는 지점으로 진행바를 이동하여 재생을 이어나갈 수 있습니다.
플레이 버튼 클릭
musicPlay.addEventListener("click", () => {
const isMusicPaused = musicWrap.classList.contains("paused"); //음악 재생중
isMusicPaused ? pauseMusic() : playMusic();
});
- musicWrap.classList.contains("paused")는 musicWrap 요소의 class 속성에 "paused"라는 클래스가 있는지 확인하여, 있다면 true, 없다면 false를 반환합니다.
- isMusicPaused 변수에 이 값을 저장한 뒤, isMusicPaused가 true이면 pauseMusic() 함수를 실행하고, false이면 playMusic() 함수를 실행합니다.
반응형