JAVASCRIPT

게임이텍트 01 - 뮤직부분

ture403 2023. 5. 3. 19:43

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90
반응형

지금까지 완성된 화면입니다.

 

 

HTML 화면입니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>GAME Effect</title>
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/style.css">
    <link rel="stylesheet" href="css/bg.css">
    <link rel="stylesheet" href="css/music.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/smoothness/jquery-ui.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
    <script defer src="js/music.js"></script>
</head>
<body>
    <div class="cursor">
        <img src="img/game_mouse01.png" alt>
    </div>
    <header id="header">
        <h1>hello Game World</h1>
        <div class="time">2023년 4월 24일 16시 50분</div>
    </header>

    <main>
        <div class="icon_box">
            <div class="icon1">
                <img src="img/file2.png" alt="뮤직">
                <span>뮤직 듣기</span>
            </div>
            <div class="icon2">
                <img src="img/file3.png" alt="뮤직">
                <span>아이 듣기</span>
            </div>
            <div class="icon3">
                <img src="img/file1.png" alt="뮤직">
                <span>소리 듣기</span>
            </div>
            <div class="icon4">
                <img src="img/file4.png" alt="뮤직">
                <span>사운 듣기</span>
            </div>
        </div>

        <!-- 뮤직 플레이어 -->
        <div class="music_wrap">
            <div class="music_inner">
                <div class="music_header">
                    <span class="left"></span>
                    <h2>music player</h2>
                    <span class="right"></span>
                </div>
                <div class="music_contents">
                    <div class="music_view">
                        <div class="images">
                            <img src="img/music_view01.png" alt="음악">
                        </div>
                        
                    </div>
                    <div class="music_control">
                        <div class="title">
                            <h3>노래 제목</h3>
                            <p>노래 작가</p>
                        </div>
                        <div class="progress">
                            <div class="bar">
                                <audio id="main-audio" src="audio/music_audio01.mp3"></audio>
                            </div>
                            <div class="timer">
                                <span class="current">0:00</span>
                                <span class="duration">3:55</span>
                            </div>
                        </div>
                        <div class="control">
                            <span>
                                <i class="repeat" id="control-repreat" title="전체 반복"></i>
                                <!--  <i class="repeat_one" id="control-repreat" title="한곡 반복"></i>
                                <i class="shuffle" id="control-repreat" title="랜덤 반복"></i> -->
                            </span>
                            <span>
                                <i class="prev" id="control-prev" title="이전곡 재생"></i>
                            </span>
                            <span>
                                <i class="play" id="control-play" title="재생"></i>
                            </span>
                            <span>
                                <i class="next" id="control-next" title="다음곡 재생"></i>
                            </span>
                            <span>
                                <i class="list" id="control-list" title="재생 목록"></i>
                            </span>
                            <!-- <span class ="repeat_one">한곡반복</span> -->
                            <!-- <span class="shuffle">랜덤반복</span> -->
                            <!-- <span class="stop">정지반복</span> -->
                        </div>
                    </div>
                    <div class="music_list">
                        <h3>뮤직 리스트<a href="#" class="close"></a></h3>
                        <ul>
                            <!-- <li class="active">
                                <span class="img">
                                    <img src="img/music_view01.png" alt>
                                </span>
                                <div class="title">
                                    <strong>1.lemon</strong>
                                    <em>kenzi</em>
                                </div>
                                <span class="time">3:04</span>
                            </li> -->
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <!-- 뮤직 플레이어 -->
    </main>

    <footer id="footer">
        <div class="info">현재 맥을 사용하고 있으면, 화면크기는 1920 X 760 입니다.</div>
    </footer>
    <script>
        const Header = document.querySelector("#header");
        const Time1 = document.querySelector(".time");
        const info = document.querySelector(".info");
        const iconBox = document.querySelectorAll(".icon_box  div");
        const icon1 = document.querySelector(".icon1");
        
        $(".icon1").draggable({ 
            containment: ".icon_box", 
            scroll: false ,
            start: function() {
                $(".cursor img").attr("src", "img/game_mouse01.png")
                $(".info").html("뮤직듣기가 드래그가 실행 되었습니다.");
                $("#header").css("background-color", "#EC3A8B");
            },
            drag :function() {
                $(".info").html("뮤직듣기가 드래그가 실행 중입니다..");
            },
            stop : function() {
                $(".info").html("뮤직듣기가 드래그가 중지되었습니다..");
                $("#header").css("background-color", "#000");
                setTimeout(()=>{
                    const width = window.screen.width;
                    const height = window.screen.height;
                    const os = navigator.userAgent.toLocaleLowerCase();
                    if (os.includes('win')) {
                        $(".info").html(`현재 window을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else if (os.includes('mac')) {
                        $(".info").html(`현재 mac을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else if (os.includes('android')) {
                        $(".info").html(`현재 android을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else {
                        $(".info").html(`현재 unknown을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    }
                },10000);
            }
        });
        $(".icon2").draggable({ 
            containment: ".icon_box", 
            scroll: false,  
            start: function() {
                $(".cursor img").attr("src", "img/game_mouse02.png")
                $(".info").html("뮤직듣기가 드래그가 실행 되었습니다.");
                $("#header").css("background-color", "#3B5EC3")
            },
            drag :function() {
                $(".info").html("뮤직듣기가 드래그가 실행 중입니다..");
            },
            stop : function() {
                $(".info").html("뮤직듣기가 드래그가 중지되었습니다..");
                $("#header").css("background-color", "#000");
                setTimeout(()=>{
                    const width = window.screen.width;
                    const height = window.screen.height;
                    const os = navigator.userAgent.toLocaleLowerCase();
                    if (os.includes('win')) {
                        $(".info").html(`현재 window을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else if (os.includes('mac')) {
                        $(".info").html(`현재 mac을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else if (os.includes('android')) {
                        $(".info").html(`현재 android을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else {
                        $(".info").html(`현재 unknown을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    }
                },10000);
            }
        });
        $(".icon3").draggable({ 
            containment: ".icon_box", 
            scroll: false,  
            start: function() {
                $(".cursor img").attr("src", "img/game_mouse03.png")
                $(".info").html("뮤직듣기가 드래그가 실행 되었습니다.");
                $("#header").css("background-color", "#7FFF5B")
            },
            drag :function() {
                $(".info").html("뮤직듣기가 드래그가 실행 중입니다..");
            },
            stop : function() {
                $(".info").html("뮤직듣기가 드래그가 중지되었습니다..");
                $("#header").css("background-color", "#000");
                setTimeout(()=>{
                    const width = window.screen.width;
                    const height = window.screen.height;
                    const os = navigator.userAgent.toLocaleLowerCase();
                    if (os.includes('win')) {
                        $(".info").html(`현재 window을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else if (os.includes('mac')) {
                        $(".info").html(`현재 mac을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else if (os.includes('android')) {
                        $(".info").html(`현재 android을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else {
                        $(".info").html(`현재 unknown을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    }
                },10000);
            },
        });
        $(".icon4").draggable({ 
            containment: ".icon_box", 
            scroll: false, 
            start: function() {
                $(".cursor img").attr("src", "img/game_mouse04.png")
                $(".info").html("뮤직듣기가 드래그가 실행 되었습니다.");
                $("#header").css("background-color", "#FFFF50")
            },
            drag :function() {
                $(".info").html("뮤직듣기가 드래그가 실행 중입니다..");
            },
            stop : function() {
                $(".info").html("뮤직듣기가 드래그가 중지되었습니다..");
                $("#header").css("background-color", "#000");
                setTimeout(()=>{
                    const width = window.screen.width;
                    const height = window.screen.height;
                    const os = navigator.userAgent.toLocaleLowerCase();
                    if (os.includes('win')) {
                        $(".info").html(`현재 window을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else if (os.includes('mac')) {
                        $(".info").html(`현재 mac을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else if (os.includes('android')) {
                        $(".info").html(`현재 android을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    } else {
                        $(".info").html(`현재 unknown을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
                    }
                },10000);
            },
        });
        
        window.onload = function(){
            window.addEventListener("mousemove", e=>{
            gsap.to(".cursor", {
                duration: 0, 
                left : e.pageX -5,
                top: e.pageY -5
                })
            });
            setInterval(printTime,1000)
            printAgent(); // 하단 중앙
        }
        
        function printTime(){
            let now = new Date();
            let year = now.getFullYear().toString();
            let month = (now.getMonth() + 1).toString().padStart(2, '0');
            let date = now.getDate().toString().padStart(2, '0'); 
            let hours = now.getHours().toString().padStart(2, '0');
            let minutes = now.getMinutes().toString().padStart(2, '0');
            let seconds = now.getSeconds().toString().padStart(2, '0');
            Time1.innerHTML = `${year}년 ${month}월 ${date}일 ${hours}시 ${minutes}분 ${seconds}초`;
        }

        function printAgent() {
            const width = window.screen.width;
            const height = window.screen.height;
            const os = navigator.userAgent.toLocaleLowerCase();
            if (os.includes('win')) {
                $(".info").html(`현재 window을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
            } else if (os.includes('mac')) {
                $(".info").html(`현재 mac을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
            } else if (os.includes('android')) {
                $(".info").html(`현재 android을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
            } else {
                $(".info").html(`현재 unknown을 사용하고 있으면, 화면크기는 ${width} X ${height} 입니다.`);
            }
        }
        


        iconBox.forEach((icon, index) => {
            icon.addEventListener("click", () => {
                const colors = ["#EC3A8B", "#3B5EC3", "#7FFF5B", "#FFFF50"];
                Header.style.backgroundColor = colors[index];
                if (index === 3) {
                    Header.style.color = "#FFFF50";
                } else {
                    Header.style.color = "";
                }
            });
        });
        
    </script>
</body>
</html>

JS코드입니다.

//전체 이미지와 오디오 객체에 저장
const allMusic = [
    {
        name : "1. 저리가라",
        artist : "partick",
        img : "music_view01",
        audio : "music_audio01"
    },{
        name : "2. 저리가라",
        artist : "partick",
        img : "music_view02",
        audio : "music_audio02"
    },{
        name : "3. 저리가라",
        artist : "partick",
        img : "music_view03",
        audio : "music_audio03"
    },{
        name : "4. 저리가라",
        artist : "partick",
        img : "music_view04",
        audio : "music_audio04"
    },{
        name : "5. 저리가라",
        artist : "partick",
        img : "music_view05",
        audio : "music_audio05"
    },{
        name : "6. 저리가라",
        artist : "partick",
        img : "music_view06",
        audio : "music_audio06"
    },{
        name : "7. 저리가라",
        artist : "partick",
        img : "music_view07",
        audio : "music_audio07"
    },{
        name : "8. 저리가라",
        artist : "partick",
        img : "music_view08",
        audio : "music_audio08"
    },{
        name : "9. 저리가라",
        artist : "partick",
        img : "music_view09",
        audio : "music_audio09"
    },{
        name : "10. 저리가라",
        artist : "partick",
        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 .images 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 musicProgressCurrent = musicWrap.querySelector(".progress .timer .current");
const musicProgressDuration = musicWrap.querySelector(".progress .timer .duration");
const musicRepeat = musicWrap.querySelector("#control-repreat");
const musicListBtn = musicWrap.querySelector("#control-list");
const musicList  = musicWrap.querySelector(".music_list");
const musicListUl  = musicWrap.querySelector(".music_list ul");
const musicListClose  = musicWrap.querySelector(".music_list h3 .close");


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].name; //뮤직이미지 alt
    musicAudio.src =`audio/${allMusic[num-1].audio}.mp3`; //뮤직이미지 alt
}

//재생버튼
const playMusic = () => {
    musicWrap.classList.add("paused"); //paused를 클래스에 추가
    musicplay.setAttribute("title", "정지"); //musicplay에 title 을 정지로 변경
    musicplay.setAttribute("class", "stop"); //musicplay에 class 을 stop로 변경

    musicAudio.play();
}

//정지버튼
const pauseMusic = () => {
    musicWrap.classList.remove("paused");
    musicplay.setAttribute("title", "재생");
    musicplay.setAttribute("class", "play");
    
    musicAudio.pause();
}

//이전 곡 듣기
const prevMusic = () => {

    musicIndex == 1 ? musicIndex = allMusic.length : musicIndex--;
    loadMusic(musicIndex);
    playMusic();
    playListMusic();
}

//다음 곡 듣기
const nextMusic = () => {
    // musicIndex++;
    // if(musicIndex > 10)musicIndex = 1;

    musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++;
    loadMusic(musicIndex);
    playMusic();
    playListMusic();
}

// 뮤직 진행바
musicAudio.addEventListener("timeupdate", e => {
    const currentTime = e.target.currentTime; //현재 재생되는 시간
    const duration = e.target.duration; //오디오의 총 길이
    let progressWidth = (currentTime / duration) *100; //전체길이 /현재진행되는 시간
    musicProgressBar.style.width = `${progressWidth}%`;

    //전체 시간
    musicAudio.addEventListener("loadeddata",()=>{
        let audiodrutaion = musicAudio.duration;
        // console.log(audiodrutaion)
        let totalMin = Math.floor(audiodrutaion / 60);
        let totalSec = Math.floor(audiodrutaion % 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;
})
//반복 버튼 클릭
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;
    }
})
//오디오 끝나면
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(randomIndex);
            playMusic();
        break;
    }
    playListMusic();
});

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

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

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

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

//뮤직 리스트 닫기
musicListClose.addEventListener("click",()=>{
    musicList.classList.remove("show");
});

//뮤직 리스트 규현하기
for(let i=0; i<allMusic.length; i++){
    let li = `
        <li data-index="${i+1}">
        <span class="img">
            <img src="img/${allMusic[i].img}.png" alt=${allMusic[i].name}>
        </span>
        <div class="title">
            <strong>${allMusic[i].name}</strong>
            <em>${allMusic[i].artist}</em>
            <audio class ="${allMusic[i].audio}" src="audio/${allMusic[i].audio}.mp3"></audio>
        </div>
        <span class="audio-duration" id="${allMusic[i].audio}">3:04</span>
        </li> 
    `;
    // musicListUl.innerHTML += li;
    musicListUl.insertAdjacentHTML("beforeend",li);

    //리스트에서 시간을 표시할 선택자 
    let liAudioDuration = musicListUl.querySelector(`#${allMusic[i].audio}`);

    //리스트에서 오디오 파일 가져오기
    let liAudio = musicList.querySelector(`.${allMusic[i].audio}`);
    liAudio.addEventListener("loadeddata",()=>{
        let audiodrutaion = liAudio.duration;
        let totalMIn = Math.floor(audiodrutaion / 60);
        let totalSec = Math.floor(audiodrutaion % 60);
        if(totalSec <10 ) totalSec =`0${totalSec}`;
        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");
        musicListAll[i].setAttribute("onclick", "clicked(this)");

        if(musicListAll[i].classList.contains("playing")){
            musicListAll[i].classList.remove("playing");
            let dataAudioDuration = audioTag.getAttribute("data-duration");
            audioTag.innerText= dataAudioDuration;
        }
        if(musicListAll[i].getAttribute("data-index") == musicIndex){
            musicListAll[i].classList.add("playing");
            audioTag.innerText="재생중";
        }
    }
}

playListMusic();

// 뮤직 리스크를 클릭하면
function clicked(el){
    let getIndex = el.getAttribute("data-index");
    // alert(getIndex);
    musicIndex = getIndex;
    loadMusic(musicIndex);
    playMusic();
    playListMusic();
}

// 그런데 load 이벤트는 문서내의 모든 리소스(이미지, 스크립트)의
// 다운로드가 끝난 후에 실행된다. 이것을 에플리케이션의 구동이
// 너무 지연되는 부작용을 초래할 수 있다.
window.addEventListener("DOMContentLoaded", () => {
    loadMusic(musicIndex);
});
// DOMContentLoaded는 문서에서 스크립트 작업을 할 수 있을 때
// 실행되기 때문에 이미지 다운로드를 기다릴 필요가 없다.
// window.addEventListener('DOMContentLoaded', function(){
//     console.log('DOMContentLoaded');
// })


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

이 코드는 JavaScript 프로그램으로 allMusic이라는 객체 배열을 정의합니다. 각각의 객체는 음악 트랙의 이름, 아티스트, 이미지 및 오디오 소스 파일과 같은 정보를 포함합니다. 또한 음악 플레이어 인터페이스를 표시하고 제어하는 데 사용되는 다양한 HTML 요소를 선언합니다.

프로그램은 loadMusic 함수와 같이 음악 플레이어의 다른 측면을 처리하는 여러 함수를 정의합니다. loadMusic 함수는 지정된 음악 트랙을 플레이어에 로드하고, playMusic과 pauseMusic 함수는 현재 트랙의 재생을 제어합니다. prevMusic와 nextMusic 함수는 사용자가 트랙 사이를 이동할 수 있도록 합니다. musicAudio 함수는 진행 막대를 업데이트하여 현재 트랙의 위치를 보여줍니다.

또한 프로그램은 사용자 조작에 대응하는 이벤트 리스너도 포함합니다. 예를 들어 play/pause, prev 및 next 버튼을 클릭하거나 진행 막대를 클릭하여 트랙의 다른 지점으로 이동할 수 있습니다. 마지막으로, 프로그램은 현재 재생 중인 트랙을 추적하는 변수 musicIndex를 정의합니다.