728x90
gameEffect | ๐พ๋ ๋ ๋ฎค์ง ํ๋ ์ด์ด ๋ง๋ค๊ธฐ๐พ
1. ์ฌ์ดํธ ๊ตฌ์กฐ ์ดํด๋ณด๊ธฐ
HTML ์ดํด๋ณด๊ธฐ
<!-- music player -->
<div class="music__wrap">
<div class="music__inner">
<div class="music__header">
<div>***</div>
<h2>Music Player</h2>
<div>+++</div>
</div>
<div class="music__contents">
<div class="music__view">
<div class="img">
<img src="../assets/img/music_view01.png" alt="">
</div>
<div class="title">
<h3>A Year Ago</h3>
<p>NETFFEX</p>
</div>
<div class="volume">
<input type="range" id="volume-control" min="0.1" max="10">
</div>
</div>
<div class="music__control">
<div class="progress">
<div class="bar">
<audio id="main-audio" src="../assets/audio/music_audio01.mp3"></audio>
</div>
<div class="timer">
<span class="current">0:00</span>
<span class="duration">4:00</span>
</div>
</div>
<div class="control">
<i title="์ ์ฒด ๋ฐ๋ณต" class="repeat" id="control-repeat"></i>
<!-- <i title="ํ๊ณก ๋ฐ๋ณต" class="repeat_one"></i>
<i title="๋๋ค ๋ฐ๋ณต" class="shuffle"></i> -->
<i title="์ด์ ๊ณก ์ฌ์" class="prev" id="control-prev"></i>
<div class="center">
<i title="์ฌ์" class="play" id="control-play"></i>
<!-- <i title="์ ์ง" class="stop"></i> -->
</div>
<i title="๋ค์๊ณก ์ฌ์" class="next" id="control-next"></i>
<i title="์ฌ์ ๋ชฉ๋ก" class="list" id="control-list"></i>
</div>
</div>
</div>
<div class="music__footer">
<div class="music__list">
<h3><span class="list"></span>๋ฎค์ง ๋ฆฌ์คํธ<a href="#" class="close"></a></h3>
<ul>
<!-- <li>
<strong>์ ๋ชฉ</strong>
<em>์ํฐ์คํธ</em>
<span>์ฌ์์๊ฐ</span>
</li> -->
</ul>
</div>
</div>
</div>
</div>
<!-- //music player -->
CSS ์ดํด๋ณด๊ธฐ
<style>
@import url('https://webfontworld.github.io/Cafe24SsurroundAir/Cafe24SsurroundAir.css');
.music__wrap {
display: none;
}
.music__wrap.show {
display: block;
}
.music__inner {
width: 450px;
background: rgba(0,0,0,0.6);
backdrop-filter: blur(5px);
position: absolute;
right: 100px;
top: 100px;
padding: 10px;
padding-top: 0;
}
.music__header {
width: 100%;
height: 30px;
display: flex;
align-items: center;
justify-content: space-between;
color: #fff;
}
.music__header h2 {
font-size: 14px;
}
.music__contents {
background: rgba(255,255,255,0.5);
width: 100%;
}
.music__view {
display: flex;
padding: 20px;
}
.music__view .img {
width: 30%;
}
.music__view .img img {
width: 100%;
}
.music__view .title {
width: 70%;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.music__view .title h3 {
margin-bottom: 10px;
font-size: 30px;
line-height: 1.2;
}
.music__view .title p {
font-family: 'Cafe24SsurroundAir';
text-transform: uppercase;
}
#volume-control {
transform: rotate(270deg);
position: absolute;
top: 100px;
right: -35px;
}
.volume input[type=range] {
-webkit-appearance: none;
background: #000;
border-radius: 50px;
}
.volume input[type=range]:focus {
outline: none;
}
/* .volume input[type=range]::-ms-track {
cursor: pointer;
background: #fff;
border-color: #000;
color: #000;
} */
.volume input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
background: #ffffff;
cursor: pointer;
border: 1px solid #000000;
height: 20px;
width: 10px;
margin-bottom: -7px;
margin-top: -7.5px;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border-radius: 3px;
}
.music__control {
width: 100%;
height: 100px;
padding: 20px;
padding-top: 0;
}
.music__control .progress {
width: 100%;
height: 6px;
background: #000;
border-radius: 5px;
}
.music__control .progress .bar {
width: 0;
height: inherit;
background: #73FBF9;
border-radius: 5px;
}
.music__control .progress .timer {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 3px;
}
.music__control .control {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 40px;
padding: 0 40px;
}
.music__control .control i {
background-color: #ccc;
scale: 1.2;
}
.music__control .control .repeat {
display: block;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
background-position: 96px 0;
}
.music__control .control .repeat:hover {
background: url(../img/music_control_over_icon.svg);
background-position: 96px 0;
}
.music__control .control .repeat_one {
display: block;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
background-position: 72px 0;
}
.music__control .control .repeat_one:hover {
background: url(../img/music_control_over_icon.svg);
background-position: 72px 0;
}
.music__control .control .shuffle {
display: block;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
background-position: 48px -2.5px;
}
.music__control .control .shuffle:hover {
background: url(../img/music_control_over_icon.svg);
background-position: 48px -2.5px;
}
.music__control .control .prev {
display: block;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
background-position: 168px 0;
}
.music__control .control .prev:hover {
background: url(../img/music_control_over_icon.svg);
background-position: 168px 0;
}
.music__control .control .next {
display: block;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
background-position: 144px 0;
}
.music__control .control .next:hover {
background: url(../img/music_control_over_icon.svg);
background-position: 144px 0;
}
.music__control .control .center {
/* width: 48px; */
display: flex;
align-items: center;
justify-content: space-between;
}
.music__control .control .play {
display: block;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
}
.music__control .control .play:hover {
background: url(../img/music_control_over_icon.svg);
}
.music__control .control .stop {
display: block;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
background-position: -24px 0;
}
.music__control .control .stop:hover {
background: url(../img/music_control_over_icon.svg);
background-position: -24px 0;
}
.music__control .control .list {
display: block;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
background-position: 120px 0;
}
.music__control .control .list:hover {
background: url(../img/music_control_over_icon.svg);
background-position: 120px 0;
}
.music__footer {
background: rgba(255,255,255,0.5);
}
.music__list {
padding: 20px;
padding-top: 0;
display: none;
}
.music__list.show {
display: block;
}
.music__list h3 {
font-size: 24px;
border-top: 2px solid #000;
padding-top: 10px;
margin-bottom: 10px;
position: relative;
}
.music__list h3 .list {
display: inline-block;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
background-position: 96px 0;
margin-right: 10px;
vertical-align: -5px;
}
.music__list h3 .close {
position: absolute;
top: 10px;
right: 0;
width: 24px;
height: 24px;
background: url(../img/music_control_icon.svg);
background-position: 24px 0;
margin-right: 5px;
vertical-align: -5px;
}
.music__list ul {
max-height: 200px;
overflow-y: scroll;
}
.music__list li {
border-bottom: 1px solid #000;
list-style: none;
position: relative;
padding: 7px 0 5px;
}
.music__list li:hover {
color: #fff;
}
.music__list li.playing {
color: #73FBF9;
/* background-color: rgba(0,0,0,0.3); */
}
.music__list li strong {
display: block;
font-size: 20px;
margin-bottom: 4px;
}
.music__list li em {
font-style: normal;
}
.music__list li span {
position: absolute;
right: 0;
top: 25px;
}
</style>
3. script ์ดํด๋ณด๊ธฐ
๐ง ์ ํ์ ๋ง๋ค๊ธฐ
<script>
const allMusic = [
{
name : "1. A Year Ago",
artist : "NETFFEX",
img : "music_view01",
audio : "music_audio01"
},
{
name : "2. As You Fade Away",
artist : "NETFFEX",
img : "music_view02",
audio : "music_audio02"
},
{
name : "3. Believe",
artist : "NETFFEX",
img : "music_view03",
audio : "music_audio03"
},
{
name : "4. Go!",
artist : "NETFFEX",
img : "music_view04",
audio : "music_audio04"
},
{
name : "5. Good day (Wake up)",
artist : "NETFFEX",
img : "music_view05",
audio : "music_audio05"
},
{
name : "6. Play Dead",
artist : "NETFFEX",
img : "music_view06",
audio : "music_audio06"
},
{
name : "7. Ruthless",
artist : "NETFFEX",
img : "music_view07",
audio : "music_audio07"
},
{
name : "8. Something You Could Never Own",
artist : "NETFFEX",
img : "music_view08",
audio : "music_audio08"
},
{
name : "9. Take Me Back",
artist : "NETFFEX",
img : "music_view09",
audio : "music_audio09"
},
{
name : "10. Til I Hear'em Say (Inst)",
artist : "NETFFEX",
img : "music_view10",
audio : "music_audio10"
}
]
const musicWrap = document.querySelector(".music__wrap");
const musicView = musicWrap.querySelector(".music__view .img img");
const musicName = musicWrap.querySelector(".music__view .title h3");
const musicArtist = musicWrap.querySelector(".music__view .title p");
const musicAudio = musicWrap.querySelector("#main-audio");
const musicRepeat = musicWrap.querySelector("#control-repeat");
const musicPlay = musicWrap.querySelector("#control-play");
const musicPrevBtn = musicWrap.querySelector("#control-prev");
const musicNextBtn = musicWrap.querySelector("#control-next");
const musicListBtn = musicWrap.querySelector("#control-list");
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 musicList = musicWrap.querySelector(".music__list");
const musicListUl = musicWrap.querySelector(".music__list ul");
const musicListClose = musicWrap.querySelector(".music__list h3 .close");
</script>
๐ง ์์ ์ฌ์ํ๊ธฐ
<script>
let musicIndex = 1; // ํ์ฌ ์์
์ธ๋ฑ์ค
// ์์
์ฌ์
function loadMusic(num){
musicName.innerText = allMusic[num-1].name; // ๋ฎค์ง ์ด๋ฆ ๋ก๋
musicArtist.innerText = allMusic[num-1].artist; // ๋ฎค์ง ์ํฐ์คํธ ๋ก๋
musicView.src = `../assets/img/${allMusic[num-1].img}.png`; // ๋ฎค์ง ์ด๋ฏธ์ง ๋ก๋
musicView.alt = allMusic[num-1].name; // ๋ฎค์ง ์ด๋ฏธ์ง alt ํ๊ทธ ๋ก๋
musicAudio.src = `../assets/audio/${allMusic[num-1].audio}.mp3`; // ๋ฎค์ง ๋ก๋
}
</script>
๐ง ๋ฒํผ์ ํด๋ฆญํ์ ๋
<script>
// ์ฌ์๋ฒํผ
function playMusic(){
musicWrap.classList.add("paused");
musicPlay.setAttribute("title","์ ์ง");
musicPlay.setAttribute("class","stop");
musicAudio.play();
}
// ํ๋ ์ด ๋ฒํผ
musicPlay.addEventListener("click", () => {
const isMusicPaused = musicWrap.classList.contains("paused"); // paused๊ฐ ์๋ค๋ฉด ์์
์ด ์ฌ์์ค
isMusicPaused ? pauseMusic() : playMusic();
});
// ์ ์ง๋ฒํผ
function pauseMusic(){
musicWrap.classList.remove("paused");
musicPlay.setAttribute("title","์ฌ์");
musicPlay.setAttribute("class","play");
musicAudio.pause();
}
// ์ด์ ๊ณก ๋ฃ๊ธฐ ๋ฒํผ
function prevMusic(){
// musicIndex --
musicIndex == 1 ? musicIndex = allMusic.length : musicIndex--; // ์ฒซ๊ณก์ผ ๊ฒฝ์ฐ ๋ง์ง๋ง ์ธ๋ฑ์ค ๊ฐ์ผ๋ก, ์๋๋ฉด ์ธ๋ฑ์ค ๊ฐ 1์ฉ ์ค์ด๋ค๋๋ก
loadMusic(musicIndex);
playMusic();
playListMusic();
}
// ์ด์ ๊ณก ๋ฒํผ ํด๋ฆญ
musicPrevBtn.addEventListener("click", () => {
prevMusic();
});
// ๋ค์ ๊ณก ๋ฃ๊ธฐ ๋ฒํผ
function nextMusic(){
// musicIndex ++
musicIndex == allMusic.length ? musicIndex = 1 : musicIndex++; // ๋ง์ง๋ง ๊ณก์ผ ๊ฒฝ์ฐ ์ฒซ๋ฒ์งธ ๊ณก์ผ๋ก, ์๋๋ฉด ์ธ๋ฑ์ค ๊ฐ 1์ฉ ๋์ด๋๋๋ก
loadMusic(musicIndex);
playMusic();
playListMusic();
}
// ๋ค์๊ณก ๋ฒํผ ํด๋ฆญ
musicNextBtn.addEventListener("click", () => {
nextMusic();
});
//๋ฐ๋ณต ๋ฒํผ ํด๋ฆญ
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;
}
});
</script>
๐ง ์ค๋์ค๊ฐ ๋๋ฌ์ ๊ฒฝ์ฐ
<script>
// ์ค๋์ค๊ฐ ๋๋๋ฉด
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); // ๋๋ค ์ธ๋ฑ์ค ์์ฑ
// while๋ฌธ ๋ฌด์กฐ๊ฑด ํ๋ฒ์ ์คํ, do while ์กฐ๊ฑด์ ์๋ง์ผ๋ฉด ์คํ๋์ง ์์
do {
randomIndex = Math.floor(Math.random() * allMusic.length + 1);
} while (musicIndex == randomIndex)
musicIndex = randomIndex; // ํ์ฌ ์ธ๋ฑ์ค๋ฅผ ๋๋ค ์ธ๋ฑ์ค๋ก ๋ณ๊ฒฝ
loadMusic(musicIndex); // ๋๋ค ์ธ๋ฑ์ค๊ฐ ๋ฐ์๋ ํ์ฌ ์ธ๋ฑ์ค ๊ฐ์ผ๋ก ์์
์ ๋ค์ ๋ก๋
playMusic(); // ๋ก๋ํ ์์
์ ์ฌ์
break;
}
playListMusic(); // ์ค๋์ค๊ฐ ๋๋๋ฉด ์ฌ์๋ชฉ๋ก ์
๋ฐ์ดํธ
});
</script>
๐ง ์งํ๋ฐ ์ค์ ํ๊ธฐ
<script>
// ๋ฎค์ง ์งํ ๋ฐ
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}`; // ์ด๊ฐ ํ ์๋ฆฟ์์ผ ๋ ์์ 0์ ๋ถ์
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์ขํ๊ฐ (offsetX : ๋ถ๋ชจ๊ธฐ์ค)
let songDuration = musicAudio.duration; // ์ค๋์ค ์ ์ฒด ๊ธธ์ด
musicAudio.currentTime = (clickedOffsetX / progressWidth) * songDuration; // ๋ฐฑ๋ถ์๋ก ๋๋ ์ซ์์ ๋ค์ ์ ์ฒด ๊ธธ์ด๋ฅผ ๊ณฑํด์ ํ์ฌ ์ฌ์๊ฐ์ผ๋ก ๋ฐ๊ฟ
});
</script>
๐ง ๋ฎค์ง ๋ฆฌ์คํธ ์ค์ ํ๊ธฐ
<script>
// ๋ฎค์ง ๋ฆฌ์คํธ ๊ตฌํํ๊ธฐ
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/audio/${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"); // class์ playing ์ถ๊ฐ
audioTag.innerText = "์ฌ์์ค"; //์ฌ์์ค์ธ ์์
์ ๋ฉํธ ์ถ๊ฐ
}
musicListAll[i].setAttribute("onclick", "clicked(this)");
}
}
// ๋ฎค์ง ๋ฆฌ์คํธ ํด๋ฆญํ๋ฉด
function clicked(el){
let getLiIndex = el. getAttribute("data-index"); // ํด๋ฆญํ ๋ฆฌ์คํธ์ ์ธ๋ฑ์ค ๊ฐ์ ์ ์ฅ
musicIndex = getLiIndex; // ํด๋ฆญํ ์ธ๋ฑ์ค ๊ฐ์ ๋ฎค์ง ์ธ๋ฑ์ค์ ์ ์ฅ
loadMusic(musicIndex); // ํด๋น ์ธ๋ฑ์ค ๋ฎค์ง ๋ก๋
playMusic(); // ์์
์ฌ์
playListMusic(); // ์์
๋ฆฌ์คํธ ์
๋ฐ์ดํธ
}
window.addEventListener("load", ()=>{
loadMusic(musicIndex); //์์
์ฌ์
playListMusic(); //๋ฆฌ์คํธ ์ด๊ธฐํ
});
</script>
๐ง ๋ณผ๋ฅจ ์กฐ์ ์ถ๊ฐํ๊ธฐ
<script>
// ๋ณผ๋ฅจ ์กฐ์
const audio = document.getElementById('main-audio');
const audioVolume = document.getElementById('volume-control');
audioVolume.addEventListener("change", function(e) {
audio.volume = this.value/10;
});
</script>
'EFFECT' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
EFFECT | Parallax Scroll ํจ๊ณผ ์ ์ฉํ๊ธฐ (6) | 2022.09.06 |
---|
๋๊ธ