JAVASCRIPT

게임 이펙트 노래 재생하기 !

Kim do hyun 2023. 4. 27. 19:16
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 href="https://fonts.googleapis.com/css2?family=Poppins:wght@100;200&display=swap" rel="stylesheet">

    <link rel="stylesheet" href="css/bg2.css">
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/game.css">
    <link rel="stylesheet" href="css/music.css">
</head>
    <body>
        <div class="div">
            <p class="m">responsive gif background</p>
        </div>
        <main>
            <div class="context">
                <h1></h1>
            </div>
            <div class="area">
                <ul class="circles">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
             </div >
        </main>
        <div class="cursor">
            <img src="img/game_mouse01.png" alt>
        </div>
        <header id="header">
            <h1>KIM GAME WORLD</h1>
            <div id="time">2023년 4월 24일 09시 30분 15초</div>
        </header>

        <main>
            <div class="icon__box">
                <div class="icon1">
                    <img src="img/game_icon01.png" alt="뮤직">
                    <span>뮤직 듣기</span>
                </div>
                <div class="icon2">
                    <img src="img/game_icon02.png" alt="뮤직">
                    <span>뮤직 듣기</span>
                </div>
                <div class="icon3">
                    <img src="img/game_icon03.png" alt="뮤직">
                    <span>뮤직 듣기</span>
                </div>
                <div class="icon4">
                    <img src="img/game_icon04.png" alt="뮤직">
                    <span>뮤직 듣기</span>
                </div>
            </div>

            <!-- 뮤직 플레이어 -->
            <div class="music__wrap">
                <div class="music__inner">
                    <div class="music__header">
                        <span class="left"></span>
                        <h2>LOVE MUSIC</h2>
                        <span class="right"></span>
                    </div>
                    <div class="music__contents">
                        <div class="music__view">
                            <div class="image">
                                <img src="img/music_view10.png" alt="음악">
                            </div>
                        </div>
                        <div class="music__control">
                            <div class="title">
                                <h3>10000hour</h3>
                                <p>Dan + Shay, Justin Bieber</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-repeat" 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>
                    <div class="music__footer"></div>
                </div>
            </div>
            <!-- //뮤직 플레이어 -->
        </main>
        
        <footer id="footer">
            <div class="info"></div>
        </footer>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <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 src="js/music.js"></script>
    <script>
        $(".icon1").draggable({
            containment: ".icon__box", scroll: false,
            start: function() {
                $(".cursor img").attr("src", "img/game_mouse01.png");
                $("#header").css("background-image", "linear-gradient(90deg, #2dffbf, #ff2020)")
            },
        });
        $(".icon2").draggable({
            containment: ".icon__box", scroll: false,
            start: function() {
                $(".cursor img").attr("src", "img/game_mouse02.png");
                $("#header").css("background-color","blue");
            },
        });
        $(".icon3").draggable({
            containment: ".icon__box", scroll: false,
            start: function() {
                $(".cursor img").attr("src", "img/game_mouse03.png");
                $("#header").css("background-color","green");
            },
        });
        $(".icon4").draggable({
            containment: ".icon__box", scroll: false,
            start: function() {
                $(".cursor img").attr("src", "img/game_mouse04.png");
                $("#header").css("background-color","yellow");
            },
        });

        function displayCurrentDateTime() {
        const now = new Date();
        const year = now.getFullYear();
        const month = now.getMonth() + 1; // getMonth()는 0부터 11까지의 값을 반환하므로 1을 더해줍니다.
        const date = now.getDate();
        const hours = now.getHours();
        const minutes = now.getMinutes();
        const seconds = now.getSeconds();
        const dateTimeString = `${year}년 ${month}월 ${date}일 ${hours}시 ${minutes}분 ${seconds}초`;
        document.getElementById("time").innerHTML = dateTimeString;
      }

      // 페이지가 로드될 때마다 1초마다 현재 날짜와 시간을 업데이트합니다.
      setInterval(displayCurrentDateTime, 1000);


        window.onload = function(){
            window.addEventListener("mousemove", e => {
                gsap.to(".cursor", {
                    duration: 0,
                    left: e.pageX - 5,
                    top: e.pageY -10
                })
            });

            printTime();    // 오른쪽 상단 시간
            printAgent();    // 하단 중앙
        }

        function printAgent(){
            let os = navigator.userAgent.toLowerCase();
            let sw = screen.width;
            let sh = screen.height;
            let info = document.querySelector("#footer .info");
            if (os.indexOf("windows") >= 0) {
                info.innerHTML = "현재 윈도우를 사용하고 있으며, 화면 크기는 " + sw + "x" + sh + " 입니다."
            } else if (os.indexOf("macintosh") >= 0) {
                info.innerHTML = "현재 맥을 사용하고 있으며, 화면 크기는 " + sw + "x" + sh + " 입니다."
            } else if (os.indexOf("iphone") >= 0) {
                info.innerHTML = "현재 아이폰을 사용하고 있으며, 화면 크기는 " + sw + "x" + sh + " 입니다."
            } else if (os.indexOf("android") >= 0) {
                info.innerHTML = "현재 안드로이드 폰을 사용하고 있으며, 화면 크기는 " + sw + "x" + sh + " 입니다."
            }
        }
        printAgent();       // 하단 중앙 모니터 정보

  
        
        
    </script>
    
</body>
</html>

CSS

.music__inner {
    width: 350px;
    background: rgba(0,0,0,0.5);
    backdrop-filter: blur(20px);
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    padding: 20px 22px;
    border-radius: 20px;
    box-shadow: 0 60px 100px rgba(0,0,0,0.4);
}
.music__header {
}
.music__header h2 {
    text-align: center;
    font-size: 14px;
    padding-top: 3px;
    font-family: 'Poppins';
    font-weight: 200;
}
.music__header .left {}
.music__header .right {}
.music__contents {}
.music__view {
    position: absolute;
    left: 50%;
    transform: translate(-50%);
    top: 50px;
    padding: 0 20px 20px 20px;
    width: 90%;
}
.music__view .image {
}
.music__view .image img {
    border-radius: 20px;
    box-shadow: 0 20px 50px rgba(246, 50, 50, 0.4);
}
.music__control {
    background-color: #fff;
    height: 400px;
    border-radius: 15px;
    margin-top: 200px;
    padding: 20px;
}
.music__control .title {
    text-align: center;
    padding-top: 120px;
    font-family: 'Poppins';
}
.music__control .title h3 {
    margin-bottom: 5px;
    color: #000;
    font-size: 20px;
}
.music__control .title p {
    color: #666;
    font-size: 16px;
    margin-bottom: 20px;
}
.music__control .progress {
    background-color: #ccc;
    height: 5px;
    background-repeat: 3px;
}
.music__control .progress .bar {
    width: 0%;
    background-color: #000;
    height: 5px;
    border-radius: 3px;
}
.music__control .progress .timer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 3px;
}
.music__control .progress .timer span {
    color: #000;
    font-size: 12px;
}
.music__control .control {
    width: 100%;
    margin-top: 40px;
    color: #000;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.music__control .control span {
    display: inline-block;
    width: 40px;
    height: 40px;
}
.music__control .control span:active {
    background-color: #eaeaea;
    border-radius: 50%;
}
.music__control .control span i {
    width: 40px;
    height: 40px;
    display: block;
    background-image: url(../img/music_control.svg);
    background-size: 500px;
}
.music__control .control span i.repeat {
    background-position: 0 0;
}
.music__control .control span i.prev {
    background-position: -120px 0;
}
.music__control .control span i.play {
    background-position: -160px 0;
}
.music__control .control span:nth-child(3){
    background-image: linear-gradient(90deg , #2dffbf, #2079ff);
    border-radius: 50%;
}
.music__control .control span i.next {
    background-position: -240px 0;
}
.music__control .control span i.list {
    background-position: -280px 0;
}
.music__control .control span i.repeat__one {
    background-position: -40px 0;
}
.music__control .control span i.shuffle {
    background-position: -80px 0;
}
.music__control .control span i.stop {
    background-position: -200px 0;
}
.music__footer {}

코드 설명

뮤직 컨트롤러가 출력될수 있게 컨트롤러의 포지션을 지정해줍니다. 

 

 

JAVASCRIPT

const allMusic = [
    {
        name : "1. 10000 hours",
        artist : "Dan + Shay, Justin Bieber",
        img: "music_view01",
        audio: "music_audio01"
    }, {
        name : "2. Loving You Girl ft. Hkeem",
        artist : "Peder Elias",
        img: "music_view02",
        audio: "music_audio02"
    }, {
        name : "3. Shape Of You",
        artist : "JFlaMusic",
        img: "music_view03",
        audio: "music_audio03"
    }, {
        name : "4. 저리가라",
        artist : "아티스트이름",
        img: "music_view04",
        audio: "music_audio04"
    }, {
        name : "5. 저리가라",
        artist : "아티스트이름",
        img: "music_view05",
        audio: "music_audio05"
    }, {
        name : "6. 저리가라",
        artist : "아티스트이름",
        img: "music_view06",
        audio: "music_audio06"
    }, {
        name : "7. 저리가라",
        artist : "아티스트이름",
        img: "music_view07",
        audio: "music_audio07   "
    }, {
        name : "8. 저리가라",
        artist : "아티스트이름",
        img: "music_view08",
        audio: "music_audio08"
    }, {
        name : "9. 저리가라",
        artist : "아티스트이름",
        img: "music_view09",
        audio: "music_audio09"
    },{
        name : "10. 저리가라",
        artist : "아티스트이름",
        img: "music_view010",
        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 musicProgress = musicWrap.querySelector(".progress");
const musicProgressBar = musicWrap.querySelector(".progress .bar");
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].name;                           //뮤직 이미지 alt
    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 = () => {
    musicIndex == 1 ? musicIndex = 10 : musicIndex--;
    // if(musicIndex == 0) musicIndex = 10;
    loadMusic(musicIndex)
    playMusic();
};

// 다음 곡 듣기 버튼
const nextMusic = () => {
    musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++;
    // if(musicIndex == 10) musicIndex = 1;
    loadMusic(musicIndex)
    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}`;
        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 clickOffsetX = e.offsetX;   //진행바를 기준으로 측정되는 X값 좌표
    let songDuration = musicAudio.duration;     //오디오 전체 길이
    //백분위로 나눈 숫자에 다시 전체 길이를 곱해 현재 재생값으로 바꿈
    musicAudio.currentTime = (clickOffsetX /progressWidth) * songDuration;
});

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

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

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


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

코드 설명

loadMusic(num): 해당 함수는 매개변수 num으로 전달된 인덱스에 해당하는 음악 정보를 가져와서 해당 음악의 이름, 아티스트, 이미지, 오디오 파일 등을 화면에 출력하는 역할을 합니다.

playMusic(): 해당 함수는 음악을 재생하는 역할을 합니다. 먼저, musicWrap 클래스에 "paused" 클래스를 추가하고, musicPlay 요소의 title 속성과 class 속성을 각각 "정지"와 "stop"으로 변경합니다. 그리고, HTMLAudioElement 객체의 play() 메서드를 호출하여 음악을 재생합니다.

pauseMusic(): 해당 함수는 음악을 일시 정지하는 역할을 합니다. 먼저, musicWrap 클래스에서 "paused" 클래스를 제거하고, musicPlay 요소의 title 속성과 class 속성을 각각 "재생"과 "play"로 변경합니다. 그리고, HTMLAudioElement 객체의 pause() 메서드를 호출하여 음악을 일시 정지합니다.

prevMusic(): 해당 함수는 이전 곡을 재생하는 역할을 합니다. 현재 재생 중인 음악의 인덱스를 감소시키고, loadMusic(num) 함수와 playMusic() 함수를 호출하여 이전 곡을 화면에 출력하고 재생합니다.

nextMusic(): 해당 함수는 다음 곡을 재생하는 역할을 합니다. 현재 재생 중인 음악의 인덱스를 증가시키고, loadMusic(num) 함수와 playMusic() 함수를 호출하여 다음 곡을 화면에 출력하고 재생합니다.

musicAudio.addEventListener("timeupdate", e => {...}): 해당 이벤트는 오디오의 현재 재생 위치가 변경될 때마다 발생합니다. 이벤트 핸들러 함수에서는 현재 재생 위치와 오디오 파일의 전체 길이를 계산하여 진행 바와 현재 재생 시간, 전체 재생 시간을 출력하는 역할을 합니다.

musicProgress.addEventListener("click", (e) => {...}): 해당 이벤트는 진행 바를 클릭하면 발생합니다. 이벤트 핸들러 함수에서는 클릭한 위치를 기준으로 현재 재생 위치를 계산하여 오디오를 해당 위치로 이동시키는 역할을 합니다.

musicPlay.addEventListener("click", () => {...}): 해당 이벤트는 플레이 버튼을 클릭하면 발생합니다. 이벤트 핸들러 함수에서는 현재 음악이 일시 정지 중인지를 판별하고, isMusicPaused 변수에 저장합니다. isMusicPaused 변수의 값에 따라 pauseMusic() 함수 또는 playMusic() 함수를 호출하여 음악을 일시 정지하거나 재생하는 역할을 합니다.

 

musicAudio.addEventListener("timeupdate", e => { ... }); : 뮤직 플레이어에서 음악의 현재 상태가 변경될 때마다 호출되는 이벤트 리스너입니다. 이 리스너는 e.target.currentTime으로 현재 재생 시간과 e.target.duration으로 오디오의 총 길이를 가져와 progressWidth를 계산합니다. 이후 musicProgressBar.style.width를 설정하여 진행바의 길이를 변경하고, 음악의 전체 길이와 현재 재생 시간을 분:초 형식으로 표시합니다.

musicAudio.addEventListener("loadeddata", () => { ... }); : 뮤직 플레이어에서 음악 파일이 로드되면 호출되는 이벤트 리스너입니다. 이 리스너는 musicAudio.duration으로 오디오의 총 길이를 가져와 분:초 형식으로 변환하여 musicProgressDuration.innerText에 표시합니다.

musicProgress.addEventListener("click", (e) => { ... }); : 진행바를 클릭하면 호출되는 이벤트 리스너입니다. 클릭한 위치의 좌표를 계산하여 musicAudio.currentTime으로 현재 재생 시간을 설정합니다.

musicPlay.addEventListener("click", () => { ... }); : 플레이 버튼을 클릭하면 호출되는 이벤트 리스너입니다. 현재 재생 상태를 확인하여 일시정지 상태이면 pauseMusic()을 호출하고, 그렇지 않으면 playMusic()을 호출합니다.

musicPrevBtn.addEventListener("click", () => { ... }); : 이전 곡 버튼을 클릭하면 호출되는 이벤트 리스너입니다. prevMusic() 함수를 호출하여 이전 곡을 재생합니다.

musicNextBtn.addEventListener("click", () => { ... }); : 다음 곡 버튼을 클릭하면 호출되는 이벤트 리스너입니다. nextMusic() 함수를 호출하여 다음 곡을 재생합니다.

window.addEventListener("load", () => { ... }); : 페이지가 로드되면 호출되는 이벤트 리스너입니다. loadMusic(musicIndex)를 호출하여 초기 음악 파일을 로드하고, musicAudio.play()를 호출하여 음악을 자동으로 재생합니다.