기초부터 시작하는 코딩/Javascript

Javascript를 이용한 사이트 만들기! - 게임 효과 사이트 만들기02

kebab00 2023. 4. 27. 22:41

728x90

- 오늘은 저번에 했던 게임 이펙트 입니다.

- 이번에는 음악 플레이어를 만들어 주었습니다.

- 버튼을 누르면 다음곡,이전곡,재생이 되게 해주었고 원하는 시간 대로 이동할 수 있도록 바에 효과를 주었습니다.

- 추가된 코드를 보시죠

- 자바 스크립트만 보시죠

const allMusic = [
    {
        name : "1.Deck The Halls - DJ Williams",
        artist : "몰루",
        img: "music_view01",
        audio: "music_audio01"
    }, {
        name : "2.Dove Love - Quincas Moreira",
        artist : "dd",
        img: "music_view02",
        audio: "music_audio02"
    }, {
        name : "3.Frightmare - Jimena Contreras",
        artist : "dd",
        img: "music_view03",
        audio: "music_audio03"
    }, {
        name : "4.Ice & Fire - King Canyon",
        artist : "dd",
        img: "music_view04",
        audio: "music_audio04"
    }, {
        name : "5.Illusions - Anno Domini Beats",
        artist : "dd",
        img: "music_view05",
        audio: "music_audio05"
    }, {
        name : "6.In Memory of Jean Talon - The Mini Vandals",
        artist : "dd",
        img: "music_view06",
        audio: "music_audio06"
    }, {
        name : "7.Savior - Telecasted",
        artist : "dd",
        img: "music_view07",
        audio: "music_audio07"
    }, {
        name : "8.Smoke Jacket Blues - TrackTribe",
        artist : "dd",
        img: "music_view08",
        audio: "music_audio08"
    }, {
        name : "9.To Loom Is to Love - The Mini Vandals",
        artist : "dd",
        img: "music_view09",
        audio: "music_audio09"
    }, {
        name : "10.When You're Not Looking - Nathan Moore",
        artist : "dd",
        img: "music_view10",
        audio: "music_audio10"
    }
];

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 musicProgressBar = musicWrap.querySelector(".progress .bar");
const musicProgress = musicWrap.querySelector(".progress");
const musicProgressCurrent = musicWrap.querySelector(".progress .timer .current");
const musicProgressDuration = musicWrap.querySelector(".progress .timer .duration");



let musicIndex = 1; // 현재음악 인덱스

// 음악재생
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].artist; //음악 알트
    musicAudio.src = `audio/${allMusic[num-1].audio}.mp3`; // 뮤직파일 
}
//재생
const playMusic = () => {
    musicWrap.classList.add("paused");
    musicPlay.setAttribute("title", "정지");
    musicPlay.setAttribute("class", "stop");
    musicAudio.play();
}
//정지
const pauseMusic = () => {
    musicWrap.classList.remove("paused");
    musicPlay.setAttribute("title", "재생");
    musicPlay.setAttribute("class", "play");
    musicAudio.pause();
}
// 이전곡 듣기
const prevMusic = ( ) => {
    // if(musicIndex != 1){
    //     musicIndex--;
    // } else {
    //     musicIndex = allMusic.length;
    // }
    musicIndex == 1 ? musicIndex = allMusic.length : musicIndex--;
    loadMusic(musicIndex);
    playMusic();
}
// 다음곡 듣기
const nextMusic = ( ) => {
    // if(musicIndex <= allMusic.length-1){
    //     musicIndex++;
    // }else{
    //     musicIndex = 1
    // }
    musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++;

    loadMusic(musicIndex);
    playMusic();
}
//플레이 버튼 클릭
musicPlay.addEventListener("click", () => {
    const isMusicPaused = musicWrap.classList.contains("paused");   //음악 재생중
    isMusicPaused ? pauseMusic() : playMusic();
});
// 이전버튼
musicPrevBtn.addEventListener("click", ()=>{
    prevMusic();
})
// 다음버튼
musicNextBtn.addEventListener("click", ()=>{
    nextMusic();
})
// 뮤직 진행 바 
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}`
        musicProgressDuration.innerText = `${totalMin}:${totalSec}`
    })
    // 진행 시간
    let currentMin = Math.floor(currentTime / 60);
    let currentSec = Math.floor(currentTime % 60);
    if(currentSec < 10) currentSec = `0${currentSec}`
    musicProgressCurrent.innerText = `${currentMin}:${currentSec}`


});
// 진행 버튼 클릭
musicProgress.addEventListener("click",(e) => {
    let progressWidth = musicProgress.clientWidth;  //진행바 전체 길이
    let clickedOffsetX = e.offsetX; //진행바를 기준으로 측정되는 X좌표값
    let songDuration = musicAudio.duration; //오디오 전체 길이 
    // 백분위로 나눈 숫자에 다시 전체 길이를 곱해서 현재 재생값으로 바꿈
    musicAudio.currentTime = (clickedOffsetX / progressWidth) * songDuration;
})


// 플레이 버튼 클릭 했을 때 
// musicPlay.addEventListener("click", ()=> {

// });
window.addEventListener("load", () => {
    loadMusic(musicIndex);
})

- allMusic 은 음악에 대한 정보가 담긴 배열입니다 배열안에 객체의 형식으로 저장되어있습니다.

- 그리고 선택자들을 작성해준 뒤 

- musicIndex 현재 듣고 있는 음악의 번호를 저장해 줍니다.

- 그리고 loaMusic 함수에서 musicIndex를 num으로 받아온 뒤 음악이름, 작가이름등 음악의 정보를 입력해 줍니다.

- 그리고 각각 버튼들의 함수를 만들어서 버튼을 클릭했을 때 인덱스가 커지고 작아지게 해주어 다음곡, 이전곡으로 가게 해줍니다.

- 여기서 중요하게 봐야 할 게 두가지 있는데 하나는 재생과 정지가 왔다갔다 하는 토글이고 , 하나는 바를 눌렀을 때 원하는 시간대로 이동하는 방식입니다.

- 토글 방식 먼저 보시죠

//재생
const playMusic = () => {
    musicWrap.classList.add("paused");
    musicPlay.setAttribute("title", "정지");
    musicPlay.setAttribute("class", "stop");
    musicAudio.play();
}
//정지
const pauseMusic = () => {
    musicWrap.classList.remove("paused");
    musicPlay.setAttribute("title", "재생");
    musicPlay.setAttribute("class", "play");
    musicAudio.pause();
}

musicPlay.addEventListener("click", () => {
    const isMusicPaused = musicWrap.classList.contains("paused");   //음악 재생중
    isMusicPaused ? pauseMusic() : playMusic();
});

- 이렇게 세가지 함수가 필요합니다.

- 첫번재는 재생일 때 함수 입니다.

- 뮤직워랩의 클라스가 paused로 바뀌게 해주고 뮤직플레이가 stop의 클라스를 가지게 해줍니다.

- 이렇게 하면 뮤직플레이 버튼이 스탑버튼으로 바뀌게 됩니다.

- 두번째는 스탑일 때 함수 입니다.

- 아까 준 paused 클라스를 없애주고 타이틀과 클라스를 재생으로 바궈 줍니다.

- 자 이제 가장 중요한 부분입니다.

- 뮤직플레이 - 즉 버튼을 클릭했을 때 일어나는 함수 입니다. 일단 워랩에 paused클라스가 있는지 없는지 확인을 해준 뒤 

있다면 스탑일 때 함수를, 없다면 재생일 때 함수를 실행해 줍니다.

- 그다음은 바 부분입니다.

// 뮤직 진행 바 
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}`
        musicProgressDuration.innerText = `${totalMin}:${totalSec}`
    })
    // 진행 시간
    let currentMin = Math.floor(currentTime / 60);
    let currentSec = Math.floor(currentTime % 60);
    if(currentSec < 10) currentSec = `0${currentSec}`
    musicProgressCurrent.innerText = `${currentMin}:${currentSec}`


});
// 진행 버튼 클릭
musicProgress.addEventListener("click",(e) => {
    let progressWidth = musicProgress.clientWidth;  //진행바 전체 길이
    let clickedOffsetX = e.offsetX; //진행바를 기준으로 측정되는 X좌표값
    let songDuration = musicAudio.duration; //오디오 전체 길이 
    // 백분위로 나눈 숫자에 다시 전체 길이를 곱해서 현재 재생값으로 바꿈
    musicAudio.currentTime = (clickedOffsetX / progressWidth) * songDuration;
})

먼저, musicAudio 변수는 HTML 오디오 태그를 참조하고 있습니다. timeupdate 이벤트를 등록하여 음악이 재생되면 매 초마다 실행되며, 현재 재생 시간을 currentTime 변수에 저장합니다. 그리고 전체 오디오 길이를 duration 변수에 저장하고, progressWidth 변수에 현재 재생 시간의 백분율 값을 계산합니다. 계산된 값으로 musicProgressBar 요소의 너비를 조정하여 진행바를 갱신합니다. 또한, loadeddata 이벤트를 등록하여 오디오가 로딩되면 audioDuration 변수에 전체 오디오 길이를 저장하고, 이를 분:초 형식으로 변환하여 musicProgressDuration 요소에 표시합니다.

이어서, musicProgress 요소를 클릭하면 click 이벤트가 발생하며, 클릭된 X좌표 값을 clickedOffsetX 변수에 저장합니다. progressWidth 변수에는 진행바 요소의 전체 너비를 저장하고, songDuration 변수에는 오디오의 전체 길이를 저장합니다. 클릭된 X좌표 값을 백분율로 변환하고, 이를 전체 오디오 길이에 곱하여 musicAudio의 currentTime 속성에 대입하여 해당 위치부터 음악을 재생합니다.

따라서, 코드는 HTML 오디오 태그를 이용하여 음악을 재생하고, 현재 재생 시간과 전체 길이를 표시하는 UI 구현하며, 사용자가 진행바를 클릭하면 해당 위치로 이동하여 음악을 재생하는 기능을 제공합니다.

- 끝!