반응형
뮤직 플레이어 애플리케이션입니다.
index.html
<!DOCTYPE html>
<html lang="en">
<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>Music</title>
<script src="https://kit.fontawesome.com/833be080c6.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="./main.css">
<script defer src="./index.js"></script>
</head>
<body>
<!-- Container -->
<div class="player-container">
<!-- Player -->
<div class="img-container">
<img id="image" src="https://lastfm.freetls.fastly.net/i/u/500x500/30ef0d3d35720910529fe026a2d2fe7c.jpg" alt="">
<h2 id="title">Takyon (Death Yon)</h2>
<h3 id="artist">Death Grips</h3>
<div class="control">
<i class="fas fa-arrow-left" id="left"></i>
<i class="fas fa-pause" id="pause"></i>
<i class="fas fa-play" id="play"></i>
<i class="fas fa-stop" id="stop"></i>
<i class="fas fa-arrow-right" id="right"></i>
</div>
<div class="gauge-box">
<div class="time-box">
<small class="current" id="current">00:00</small>
<small class="duration" id="duration">00:00</small>
</div>
<input class="progress" type="range" value="0">
</div>
</div>
<!-- Audio object -->
<audio id="audio" src="./assets/music/Death Grips - Takyon (Death Yon).mp3"></audio>
</div>
</body>
</html>
main.css
@import url('https://fonts.googleapis.com/css2?family=Spartan:wght@400;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
background: #c9cde3;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-family: 'Spartan';
}
/* image styles */
.img-container {
height: 400px;
width: 280px;
background-color: #383636;
position: relative;
border-radius: 5px;
box-shadow: 0 0 5px 1px rgba(0, 0, 0, .3);
color: #c9cde3;
}
.img-container h2 {
width: 100%;
text-align: center;
position: absolute;
bottom:80px;
}
.img-container h3 {
width: 100%;
text-align: center;
position: absolute;
bottom: 60px;
}
/* control styles */
.control {
width: 100%;
position: absolute;
bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.control i {
margin: 0 15px;
cursor: pointer;
transition: .4s ease-in-out;
}
.control i:hover {
color: #f1851a;
}
.control i:active {
transform: scale(.85);
}
img {
height: 250px;
width: 250px;
position: absolute;
left: 50%;
top: 15px;
transform: translate(-50%, 0%);
object-fit: cover;
box-shadow: 0 0 5px 1px rgba(255, 255, 255, .3);
}
/* player guage styles */
.gauge-box {
width: 100%;
padding: 0 15px;
position: absolute;
bottom: 45px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.time-box {
width: 100%;
padding: 0 5px;
display: flex;
align-items: center;
justify-content: space-between;
}
.progress {
height: 4px;
width: 100%;
-webkit-appearance: none;
margin: 5px;
}
.progress::-webkit-slider-thumb {
box-shadow: 0px 0px 0px #000000;
border: 0px solid #000000;
height: 12px;
width: 12px;
border-radius: 50%;
background: #f1851a;
cursor: pointer;
-webkit-appearance: none;
}
.gauge-box small {
color: #c9cde3;
}
index.js
const title = document.getElementById('title')
const artist = document.getElementById('artist')
const image = document.getElementById('image')
const audio = document.getElementById('audio')
const left = document.getElementById('left')
const play = document.getElementById('play')
const pause = document.getElementById('pause')
const stop = document.getElementById('stop')
const right = document.getElementById('right')
const current = document.querySelector('.current')
const duration = document.querySelector('.duration')
const progress = document.querySelector('.progress')
const photos = [
'https://lastfm.freetls.fastly.net/i/u/500x500/30ef0d3d35720910529fe026a2d2fe7c.jpg',
'https://lastfm.freetls.fastly.net/i/u/500x500/831e96df3afd4777c7ac562537bdb356.jpg',
'https://lastfm.freetls.fastly.net/i/u/500x500/bb528670782ee23cfebc8232070f86a5.jpg',
'https://lastfm.freetls.fastly.net/i/u/500x500/008082c0cae3371b6ed6a85ea3bb15fb.jpg',
]
const audios = [
'./assets/music/Death Grips - Takyon (Death Yon).mp3',
'./assets/music/Death Grips - Get Got.mp3',
'./assets/music/Death Grips - No Love.mp3',
"./assets/music/Sleepmakeswaves - It's Dark, It's Cold, It's Winter.mp3",
]
let idx = 0
left.addEventListener('click', () => {
idx++
if (idx > photos.length - 1) idx = 0
changeImage()
changeTitleAndArtist()
changeMusic()
})
right.addEventListener('click', () => {
idx--
if (idx < 0) idx = photos.length - 1
changeImage()
changeTitleAndArtist()
changeMusic()
})
function changeImage() {
image.src = photos[idx]
}
function changeMusic() {
audio.src = audios[idx]
setTimeout(() => {
getTrackTime()
}, 200)
}
function changeTitleAndArtist() {
const song = audios[idx].replace('.mp3', '').replace('./assets/music/', '')
title.innerText = song.split(' - ')[1]
artist.innerText = song.split(' - ')[0]
}
play.addEventListener('click', () => {
audio.play()
})
pause.addEventListener('click', () => {
audio.pause()
})
stop.addEventListener('click', () => {
audio.pause()
audio.currentTime = 0
current.textContent = '00:00'
progress.value = 0
})
audio.addEventListener('ended', () => {
right.click()
audio.play()
})
audio.addEventListener('loadeddata', () => {
setTimeout(() => {
getTrackTime()
}, 200)
})
audio.addEventListener('timeupdate', (e) => {
if (!audio.paused) {
const { duration, currentTime } = e.srcElement
let min = Math.round(currentTime / 60)
let sec = Math.round(currentTime % 60)
current.textContent = `${min.toString().length < 2 ? '0' + min : min}: ${
sec.toString().length < 2 ? '0' + sec : sec
}`
progress.value = (currentTime / duration) * 100
}
})
function getTrackTime() {
const total = audio.duration
const min = Math.floor(total / 60).toString()
const sec = Math.floor(total % 60).toString()
duration.textContent = `${min.length < 2 ? '0' + min : min}: ${
sec.length < 2 ? '0' + sec : sec
}`
}
getTrackTime()
progress.addEventListener('change', (e) => {
audio.currentTime = (+e.target.value / 100) * audio.duration
})
데모
728x90
반응형
'프론트엔드 > 자바스크립트' 카테고리의 다른 글
클라이언트 측 데이터 저장소 - 웹 스토리지 (Web Storage) (0) | 2022.12.29 |
---|---|
프로젝트 - to do (0) | 2022.12.29 |
요소 지우기 (0) | 2022.12.28 |
배열 안에 객체 밸류 바꾸기 (0) | 2022.12.27 |
드래그 앤 드랍 (0) | 2022.12.26 |