본문 바로가기
Effect

gameEffect03

by 코터틀 2022. 10. 19.
반응형

gameEffect


JAVASCRIPT01

음악의 원하는 시간대를 들을 수 있도록 게이지바에 클릭 이벤트를 부여합니다.
switch문을 사용하여 전체 반복, 한곡 반복, 랜덤 반복에 기능을 부여합니다. 전체 반복 상태일 때 버튼을 클릭하면, 클래스명이 repeat_one, 타이틀이 한곡 반복으로 변경되게됩니다.
변경된 클래스 명에 따라 부여한 css로 아이콘 또한 한곡 반복 아이콘으로 변경됩니다. 쉽ㅈ...ㅛ??

// 진행 버튼 클릭
musicProgress.addEventListener("click", (e) => {
    let progressWidth = musicProgress.clientWidth; // 진행바 전체 길이
    let clickedOffsetX = e.offsetX; // 진행바 기준으로 측정되는 X 좌표값
    let songDuration = musicAudio.duration; // 오디오 전체 길이

    musicAudio.currentTime = (clickedOffsetX / progressWidth) * songDuration; // 백분위로 나눈 숫자에 다시 전체 길이를 곱해서 현재 재생값으로 바꿈
});

// 반복 버튼 클릭
musicRepeat.addEventListener("click", () => {
    let getAttr = musicRepeat.getAttribute("class");

    switch (getAttr) {
        case "repeat":
            musicRepeat.setAttribute("class", "repeat_one");
            musicRepeat.setAttribute("title", "한곡 반복");
            break;

        case "repeat_one":
            musicRepeat.setAttribute("class", "shuffle");
            musicRepeat.setAttribute("title", "랜덤 반복");
            break;

        case "shuffle":
            musicRepeat.setAttribute("class", "repeat");
            musicRepeat.setAttribute("title", "전체 반복");
            break;
    }
});

JAVASCRIPT02

음악이 끝나면 플레이어가 멈추게 되는데, 설정한 반복 기능에 따라 자동으로 다음곡으로 넘어가도록 설정해주는 이벤트를 부여합니다.
전체 반복이라면 -> 다음곡으로, 한곡 반복이라면 - > 재생, 랜덤 반복이라면 -> 랜덤 인덱스값을 생성 후 do while문을 사용하여 우선 랜덤으로 다음곡이 재생되도록 실행시키는데, 만약 현재 음악의 인덱스값과 랜덤 인덱스값이 동일하다면 음악이 중복되므로 while을 실행하게됩니다. 앞 전에 생성한 버튼들의 함수를 실행하기 위해 버튼에 클릭이벤트를 부여해줍니다.

// 오디오가 끝나면
musicAudio.addEventListener('ended', () => {
    let getAttr = musicRepeat.getAttribute('class');

    switch (getAttr) {
        case 'repeat':
            nextMusic();
            break;

        case 'repeat_one':
            playMusic();
            break;

        case 'shuffle':
            let randomIndex = Math.floor(Math.random() * allMusic.length + 1); // 랜덤 인덱스 생성
            do {
                randomIndex = Math.floor(Math.random() * allMusic.length + 1);
            } while (musicIndex == randomIndex);
            musicIndex = randomIndex; // 현재 인덱스를 랜덤 인덱스로 변경
            loadMusic(musicIndex); // 랜덤 인덱스가 반영된 현재 인덱스 값으로 음악을 다시 로드
            playMusic(); // 로드한 음악을 재생
            break;
    }
    playListMusic(); // 재생목록 업데이트

    // while, do while문 차이
    // while = 조건이 맞지 않으면 한번도 실행하지 않음(선평가 후실행)
    // do while = 조건이 맞지 않아도 한번은 실행 됨(선실행 후평가)
});

// 플레이 버튼 클릭
musicPlay.addEventListener('click', () => {
    const isMusicPause = musicWrap.classList.contains('paused'); // 음악이 재생중
    isMusicPause ? pauseMusic() : playMusic();
});

// 이전곡 버튼 클릭
musicPrevBtn.addEventListener('click', () => {
    prevMusic();
});

// 다음곡 버튼 클릭
musicNextBtn.addEventListener('click', (e) => {
    nextMusic();
});

// 뮤직 리스트 버튼
musicListBtn.addEventListener('click', () => {
    musicList.classList.add('show');
});

JAVASCRIPT03

플레이 리스트도 구현해줍니다. for문을 사용하여 li변수에 음악과 관련된 DOM정보를 저장, ul선택자에 오름차순(?)으로 변수 li 속성값이 들어가도록 합니다.
모든 음악정보를 리스트로 구현했다면, 각 음악의 재생 시간 또한 표시해줍니다. 그리고 리스트를 클릭하면 음악 또한 바뀌어야겠죠?? 세부 설명은 주석을 확인해주세요 ㅎㅎ..

// 뮤직 리스트 구현하기
for (let i = 0; i < allMusic.length; i++) {
    let li = `
    <li data-index="${i + 1}">
        <strong>${allMusic[i].name}</strong>
        <em>${allMusic[i].artist}</em>
        <audio class="${allMusic[i].audio}" src="../assets/music/${allMusic[i].audio}.mp3"></audio>
        <span class="audio-duration" id="${allMusic[i].audio}">재생시간</span>
    </li>
    `;

    // musicListUl.innerHTML += li;
    musicListUl.insertAdjacentHTML('beforeend', li);

    //리스트에 음악 시간 불러오기
    let liAudioDuration = musicListUl.querySelector(`#${allMusic[i].audio}`); //리스트에서 시간을 표시할 선택자를 가져옴
    let liAudio = musicListUl.querySelector(`.${allMusic[i].audio}`); //리스트에서 오디오를 가져옴
    liAudio.addEventListener('loadeddata', () => {
        let audioDuration = liAudio.duration; //오디오 전체 길이
        let totalMin = Math.floor(audioDuration / 60); //전체 길이를 분 단위 쪼갬
        let totalSec = Math.floor(audioDuration % 60); //초 계산
        if (totalSec < 10) totalSec = `0${totalSec}`; //앞 자리에 0 추가
        liAudioDuration.innerText = `${totalMin}:${totalSec}`; //문자열 출력
        liAudioDuration.setAttribute('data-duration', `${totalMin}:${totalSec}`); //속성에 오디오 길이 기록
    });
}

// 뮤직 리스트를 클릭하면 재생
function playListMusic() {
    const musicListAll = musicListUl.querySelectorAll('li'); // 뮤직 리스트 목록
    for (let i = 0; i < musicListAll.length; i++) {
        let audioTag = musicListAll[i].querySelector('.audio-duration');

        if (musicListAll[i].classList.contains('playing')) {
            musicListAll[i].classList.remove('playing'); // 클래스가 존재하면 삭제
            let adDuration = audioTag.getAttribute('data-duration'); // 오디오 길이 값 가져오기
            audioTag.innerText = adDuration; // 오디오 길이 값 출력
        }
        if (musicListAll[i].getAttribute('data-index') == musicIndex) {
            // 현재 뮤직 인덱스랑 리스트 인덱스 값이 같으면
            musicListAll[i].classList.add('playing'); // 클래스 playing 추가
            audioTag.innerText = '재생중'; // 재생중일 경우 재생중 멘트 추가
        }

        musicListAll[i].setAttribute('onclick', 'clicked(this)');
    }
    playMusic();
}

// 뮤직 리스트를 클릭하면
function clicked(el) {
    let getLiindex = el.getAttribute('data-index'); // 클릭한 리스트의 인덱스값을 저장
    musicIndex = getLiindex; // 클릭한 인데스 값을 뮤직 인덱스 저장
    loadMusic(musicIndex); // 해당 인덱스 뮤직 로드
    pauseMusic(); // 음악 재생
    playListMusic(); // 음악 리스트 업데이트
}

JAVASCRIPT04

드디어 마지막이네요, 간단한 열기, 닫기 기능을할 클릭 이벤트를 부여하고, 게임 이펙트 페이지를 로드하면 음악이 재생되고 리스트가 업데이트되도록 합니다.
input type = range를 사용한 볼륨 조절 버튼을 만들었습니다. 볼륨이 0일 때는 볼륨 아이콘으 변경되도록 작업도 해주었습니다.

// 뮤직 리스트 열기, 닫기
const musicFooter = document.querySelector('.music__footer');
const List = document.querySelector('.list');
const Close = document.querySelector('.close');
const MusicFolder = document.querySelector('.icon1');
const Music = document.querySelector('.music__inner');

List.addEventListener('click', () => {
    musicFooter.classList.toggle('hide');
});
Close.addEventListener('click', () => {
    musicFooter.classList.add('hide');
});
MusicFolder.addEventListener('click', () => {
    Music.classList.toggle('show');
});

window.addEventListener('load', () => {
    loadMusic(musicIndex); // 음악 재생
    playListMusic(); // 리스트 초기화
});

// 볼륨 조절
const audio = document.getElementById('main-audio');
const audioVolume = document.getElementById('volume-control');
const volumeIcon = document.querySelector('.volume_icon');
const volumeOffIcon = document.querySelector('.volumeOff_icon');

audioVolume.addEventListener('change', function (e) {
    audio.volume = this.value / 10;
    if (this.value == 0) {
        volumeIcon.classList.add('hide');
        volumeOffIcon.classList.add('show');
    } else {
        volumeIcon.classList.remove('hide');
        volumeOffIcon.classList.remove('show');
    }
});    

gameEffect01 세 번째 게시글입니다. 마지막이네요. 함수 실행문의 중요성을 깨달은 이펙트였습니다.. js 현기증나요..

반응형

'Effect' 카테고리의 다른 글

searchEffect06  (1) 2022.10.19
sliderEffect06  (1) 2022.10.19
gameEffect02  (2) 2022.10.19
gameEffect01  (1) 2022.10.19
sliderEffect05  (0) 2022.10.18

댓글


광고 준비중입니다.