์๋ฐ์คํฌ๋ฆฝํธ : ๊ฒ์ ํจ๊ณผ : ๋ฎค์ง ํ๋ ์ด์ด
์ด๋ฒ์๋ ๊ฒ์ ํจ๊ณผ์ ๋๋ค. ์ฒซ๋ฒ์งธ ์ ํ์ผ๋ก๋ ๋ฎค์ง ํ๋ ์ด์ด๋ฅผ ์์ ํ ์์ ์ ๋๋ค.
1. ์ฌ์ ์์
1-1. ๋ง์ฐ์ค ์ปค์ ๋ง๋ค๊ธฐ
const cursor = document.querySelector(".mouse__cursor");
window.addEventListener("mousemove", (e) => {
cursor.style.left = e.clientX + "px";
cursor.style.top = e.clientY + "px";
});
๊ท์ฌ์ด ์ด๋ฏธ์ง๋ก ๋ง์ฐ์ค ์ปค์๋ฅผ ๋ฐ๊พธ์ด ์ค๋๋ค. ์ด ์ ๋๋ ๊ป์ด์ฃ .
1-2. ์๊ฐ ์ถ๋ ฅํ๊ธฐ
function printTime() {
const clock = document.querySelector(".time");
const now = new Date();
let hour = now.getHours();
let minute = now.getMinutes();
let second = now.getSeconds();
if (hour > 12) hour = hour - 12;
if (hour < 10) hour = `0${hour}`;
if (minute < 10) minute = `0${minute}`;
if (second < 10) second = `0${second}`;
const nowTime = now.getFullYear() + "๋
" + (now.getMonth() + 1) + "์ " +
now.getDate() + "์ผ " + hour + ":" + minute + ":" + second;
clock.innerText = nowTime;
setTimeout("printTime()", 1000);
}
์ฐ๋ฆฌ๋ ๋จผ์ ํ์ฌ ์ฐ๋์ ๋ ์ง, ์๊ฐ์ ์ถ๋ ฅํ ๊ฒ์
๋๋ค.
์ฐ๋๋ getFullYear(), ์์ getMonth(), ์ผ์ getDate()๋ฅผ ์ด์ฉํ์ฌ ์ถ๋ ฅํ ์ ์์ต๋๋ค.
์ด ๋, getMonth()์ ๋ฐํ๊ฐ์ 1-12๊ฐ ์๋ 0-11 ์ฌ์ด์ด๊ธฐ ๋๋ฌธ์ 1์ ๋ํด์ค์ผ ํ์ฌ์ ์์๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
๊ทธ ์ด์ ๋ ๊ณต์์ ์ผ๋ก ๋ฐํ๋ ๋ฐ๋ ์์ง๋ง, ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ํด๋นํ๋ ๋ฌ์ ์ด๋ฆ์ ๊ฐ์ ธ์ฌ ๋ ํธ๋ฆฌํ๋ค๋ ์ถ์ธก์ด ์์ต๋๋ค.
์๊ฐ์ getHours(), ๋ถ์ getMinutes(), ์ด๋ getSeconds()๋ฅผ ์ด์ฉํ์ฌ ๊ฐ๊ฐ ์ถ๋ ฅํด ์ค๋๋ค.
์๊ฐ์ 24์๊ฐ์ด ์๋ 12์๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ถ๋ ฅ๋๋๋ก if๋ฌธ์ ์ฌ์ฉํ์ฌ ์์
ํด ์ฃผ์์ต๋๋ค.
๋, ๊ฐ๊ฐ์ ์๊ฐ, ๋ถ, ์ด๊ฐ 10 ๋ฏธ๋ง์ผ ๋์๋ 03์, 05๋ถ, 09์ด ๋ฑ ๋ ์๋ฆฟ์๋ก ์ถ๋ ฅ๋ ์ ์๋๋ก ์์
ํด ์ฃผ์์ต๋๋ค.
1์ด๋ง๋ค ์๊ฐ์ด ๋ฐ๋๋๋ก ํด์ผ ํ๋ฏ๋ก, setTimeout์ ์ฌ์ฉํ์ฌ 1์ด๋ง๋ค printTime() ํจ์๊ฐ ์คํ๋๊ฒ๋ ์์
ํด ์ค๋๋ค.
1-3. ํ๊ฒฝ ์ถ๋ ฅํ๊ธฐ
function printAgent() {
const agent = document.querySelector(".agent");
const os = navigator.userAgent.toLocaleLowerCase();
if (os.indexOf("window") >= 0) {
agent.innerText = "ํ์ฌ windows๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ, ํ๋ฉด ํฌ๊ธฐ๋ " + screen.width + " * " + screen.height + "์
๋๋ค.";
document.querySelector("body").classList.add("window");
} else if (os.indexOf("macintosh") >= 0) {
agent.innerText = "ํ์ฌ mac์ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ, ํ๋ฉด ํฌ๊ธฐ๋ " + screen.width + " * " + screen.height + "์
๋๋ค.";
document.querySelector("body").classList.add("mac");
} else if (os.indexOf("iphone") >= 0) {
agent.innerText = "ํ์ฌ IPhone์ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ, ํ๋ฉด ํฌ๊ธฐ๋ " + screen.width + " * " + screen.height + "์
๋๋ค.";
document.querySelector("body").classList.add("iphone");
} else if (os.indexOf("android") >= 0) {
agent.innerText = "ํ์ฌ Android๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ, ํ๋ฉด ํฌ๊ธฐ๋ " + screen.width + " * " + screen.height + "์
๋๋ค.";
document.querySelector("body").classList.add("android");
}
}
์ด๋ฒ์๋ ์ฌ์ฉ์๋ค์ ํ๊ฒฝ์ ์ถ๋ ฅํ๋๋ก ํ๊ฒ ์ต๋๋ค.
์ด๋ ๊ฒ ํ๊ฒฝ์ ๋ฐ๋ผ if๋ฌธ์ ์ฌ์ฉํ๋ฉด, ํ๊ฒฝ์ ๋ฐ๋ผ CSS ์์ค๋ฅผ ๋ฌ๋ฆฌํ์ฌ ์์
์ ํ ์ ์์ต๋๋ค.
์์ ์์ os๋ฅผ innerText๋ฅผ ์ฌ์ฉํ์ฌ ์ถ๋ ฅํด ๋ณด๋ฉด, ์๋์ฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๋ด์ฉ์ด ์ถ๋ ฅ๋ฉ๋๋ค.
mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/105.0.0.0 safari/537.36
windows, mac, iphone, android ์ฌ์ฉ์๋ค์ ํ๊ฒฝ์์๋ ๊ฐ๊ฐ windows, macintoshv, iphone, android๊ฐ ์ถ๋ ฅ๋ ๊ฒ์ ๋๋ค. indexOf๋ฅผ ํตํด ํด๋นํ๋ ๋ด์ฉ์ ๊ฒ์ํจ์ผ๋ก์จ ์ฌ์ฉ์๋ค์ ํ๊ฒฝ์ ์ ์ ์์ต๋๋ค. ํ๊ฒฝ๊ณผ ํจ๊ป ํ๋ฉด ํฌ๊ธฐ๋ ์ถ๋ ฅํด ์ค๋๋ค.
1-4. ํด๋ ๋๋๊ทธ ํจ๊ณผ
$(".icon1").draggable({
drag: function () {
$(".mouse__cursor img").attr("src", "../assets/img/effect_mouse01.png");
},
});
$(".icon2").draggable({
drag: function () {
$(".mouse__cursor img").attr("src", "../assets/img/effect_mouse02.png");
},
});
$(".icon3").draggable({
drag: function () {
$(".mouse__cursor img").attr("src", "../assets/img/effect_mouse03.png");
},
});
$(".icon4").draggable({
drag: function () {
$(".mouse__cursor img").attr("src", "../assets/img/effect_mouse04.png");
},
});
$(".icon5").draggable({
drag: function () {
$(".mouse__cursor img").attr("src", "../assets/img/effect_mouse05.png");
},
});
$(".icon6").draggable({
drag: function () {
$(".mouse__cursor img").attr("src", "../assets/img/effect_mouse06.png");
},
});
$(".music__wrap").draggable();
draggable() ํจ์๋ jQuery UI ๊ฐ ์ ๊ณตํ๋ ์ํธ์์ฉ(Interaction) ๊ธฐ๋ฅ ์ค ํ๋์
๋๋ค.
https://jqueryui.com/draggable/
์ด ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ์ ํํ ์์๋ฅผ ์์ ๋กญ๊ฒ ๋๋๊ทธํ ์ ์๊ฒ ๋ฉ๋๋ค.
๊ฐ๊ฐ์ ์์๋ฅผ ๋๋๊ทธํ ๋, ๋ง์ฐ์ค ์ปค์์ ์์์ด ์์์ ์์์ ๋ง์ถ์ด ๋ณํํ๋ ๋ฉ์ง ํจ์๋ ๋ง๋ค์ด ์ฃผ์์ต๋๋ค.
1-5. ํจ์ ์คํ์ํค๊ธฐ
window.onload = function () {
printTime();
printAgent();
};
๋ง๋ ํจ์๋ค์ ์ถ๋ ฅํด ์ค๋๋ค. window.onload๋ HTML ํ์ด์ง๊ฐ ๋ก๋๋๋ฉด ์์ ์ ์ํํ๋ค๋ ์๋ฏธ์ ๋๋ค.
2. ๋ฎค์ง ํ๋ ์ด์ด ์์
๋ณธ๊ฒฉ์ ์ผ๋ก ๋ฎค์ง ํ๋ ์ด์ด๋ฅผ ๋ง๋ค์ด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด๋ฒ์ ์์ ํ ๋ฎค์ง ํ๋ ์ด์ด์ ๋ชจ์ต์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. HTML ์์ค๋ ์๋๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์.

HTML ์์ค ๋ณด๊ธฐ
<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/effect_img01.png" alt="์ด๋ฏธ์ง1" />
</div>
<div class="title">
<h3>Loading...</h3>
<p>Loading...</p>
</div>
</div>
<div class="music__control">
<div class="volume">
vol = <span class="nowvolume">5</span>
</div>
<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">0: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>
<i title="์๋ ์๊ฒ" class="volumeDown" id="control-volDown"></i>
<i title="์ฌ์" class="play" id="control-play"></i>
<!-- <i title="์ ์ง" class="stop" id="control-stop"></i> -->
<i title="์๋ ํฌ๊ฒ" class="volumeUp" id="control-volUp"></i>
<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>Music List<span class="close" id="control-list-close"></span></h3>
<ul>
<!-- <li>
<strong>์ ๋ชฉ</strong>
<em>์ํฐ์คํธ</em>
<span>์ฌ์์๊ฐ</span>
</li> -->
</ul>
</div>
</div>
</div>
</div>
2-1. ์์ ๋ฆฌ์คํธ ์์ฑํ๊ธฐ
const allMusic = [
{ name: "Gizmo", artist: "Syn Cole", img: "effect_img01", audio: "music_audio01" },
{ name: "Clear My Head", artist: "Ellis", img: "effect_img02", audio: "music_audio02" },
{ name: "Perfect 10", artist: "Unknown Brain", img: "effect_img03", audio: "music_audio03" },
{ name: "Won't Look Back", artist: "BEAUZ & Momo", img: "effect_img04", audio: "music_audio04" },
{ name: "Chasing Ghosts", artist: "Distrion", img: "effect_img05", audio: "music_audio05" },
{ name: "Flashes", artist: "NIVIRO", img: "effect_img06", audio: "music_audio06" },
{ name: "New World", artist: "KIRA", img: "effect_img07", audio: "music_audio07" },
{ name: "Modular", artist: "Rob Gasser x Michael White x Miss Lina", img: "effect_img08", audio: "music_audio08" },
{ name: "Moonlight", artist: "Jim Yosef", img: "effect_img09", audio: "music_audio09" },
{ name: "Wanna", artist: "Ikson", img: "effect_img10", audio: "music_audio10" },
];
๋จผ์ , ์ฝ์ ํ ์์ ๋ค์ ์ ๋ชฉ, ์ํฐ์คํธ, ์ด๋ฏธ์ง, ์ค๋์ค๋ฅผ ๋ฐฐ์ด๊ณผ ๊ฐ์ฒด๋ก ์์ฑํด ์ค๋๋ค.
2-2. ์ ํ์ ๋ง๋ค๊ธฐ
// ์์
์ ๋ณด
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 musicPlay = musicWrap.querySelector("#control-play");
const musicPrevBtn = musicWrap.querySelector("#control-prev");
const musicNextBtn = musicWrap.querySelector("#control-next");
const musicRepeat = musicWrap.querySelector("#control-repeat");
const musicVolUp = musicWrap.querySelector("#control-volUp");
const musicVolDown = musicWrap.querySelector("#control-volDown");
// ๋ฎค์ง ๋ฆฌ์คํธ
const musicListBtn = musicWrap.querySelector("#control-list");
const musicList = musicWrap.querySelector(".music__list");
const musicListUl = musicWrap.querySelector(".music__list ul");
const musicListCloseBtn = musicWrap.querySelector("#control-list-close");
// ๋ฐ
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");
์ ํ์๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ์ ๋ฆฌํ๊ณ ์ถ์์ง๋ง... ๋๋ฌด ๋ง์ผ๋ฏ๋ก ํ๋ฒ์ ์ ๋ฆฌํ๋๋ก ํ๊ฒ ์ต๋๋ค.
2-3. ์์ ์ ๋ณด ์ ๋ ฅํ๊ธฐ
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`; // ๋ฎค์ง ๋ก๋
}
let musicIndex = 1; // ํ์ฌ ์์
์ธ๋ฑ์ค
musicAudio.volume = 0.5;
๊ฐ ์ค๋์ค๋ค์ ๋ณผ๋ฅจ์ 0-1 ์ฌ์ด๋ก ์ง์ ํ ์ ์์ต๋๋ค. ์ด๊ธฐ ๋ณผ๋ฅจ์ ๊ทธ ์ค๊ฐ์ธ 0.5๋ก ์์ ํด ์ฃผ์์ต๋๋ค.
2-4. ์ฌ์ ๋ฒํผ ์์ ํ๊ธฐ
function playMusic() {
musicWrap.classList.add("paused");
musicPlay.setAttribute("id", "control-stop");
musicPlay.setAttribute("class", "stop");
musicAudio.play();
}
function pauseMusic() {
musicWrap.classList.remove("paused");
musicPlay.setAttribute("id", "control-play");
musicPlay.setAttribute("class", "play");
musicAudio.pause();
}
musicPlay.addEventListener("click", () => {
const isMusicPaused = musicWrap.classList.contains("paused");
isMusicPaused ? pauseMusic() : playMusic();
});
๋จผ์ , ์ฌ์ ๋ฒํผ์ ์์
ํด ์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค. playMusic() ํจ์๋
์ฌ์ ๋ฒํผ์ ๋๋ ์ ๋, ์ ์ง ๋ฒํผ์ด ๋ํ๋๊ฒ ํ๊ณ , musicWrap์ paused ํด๋์ค๋ฅผ ์ถ๊ฐํฉ๋๋ค.
pauseMusic() ํจ์๋ ์ ์ง ๋ฒํผ์ ๋๋ ์ ๋, ์ฌ์ ๋ฒํผ์ด ๋ํ๋๊ฒ ํ๊ณ , paused ํด๋์ค๋ฅผ ์ ๊ฑฐํฉ๋๋ค.
์ฆ, musicWrap์ ํด๋์ค ์ค paused๊ฐ ์๋ค๋ฉด ์์
์ด ์ฌ์ ์ค์ด๋ผ๋ ์๋ฏธ์
๋๋ค.
์ดํ, ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค. ์ฌ์ ๋ฒํผ์ ํด๋ฆญํ์ ๋, ์์
์ด ์ฌ์ ์ค์ด๋ผ๋ฉด
์์
์ pauseMusic() ํจ์๋ฅผ ์คํํ๊ณ , ์ ์ง ์ค์ด๋ผ๋ฉด playMusic() ํจ์๋ฅผ ์คํ์ํต๋๋ค.
2-5. ์ด์ ๊ณก ๋ฒํผ, ๋ค์ ๊ณก ๋ฒํผ ์์ ํ๊ธฐ
function prevMusic() {
musicIndex == 1 ? (musicIndex = allMusic.length) : musicIndex--;
loadMusic(musicIndex);
playMusic();
playListMusic();
}
function nextMusic() {
musicIndex == allMusic.length ? (musicIndex = 1) : musicIndex++;
loadMusic(musicIndex);
playMusic();
playListMusic();
}
musicPrevBtn.addEventListener("click", () => {
prevMusic();
});
musicNextBtn.addEventListener("click", () => {
nextMusic();
});
์ด์ ๋ฒํผ, ๋ค์ ๋ฒํผ๋ ์์
ํด ์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค.
์ด์ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์ด์ ์์
์ด ์ฌ์๋๋๋ก ํ๊ณ ,
์ฒซ๋ฒ์งธ ์์
์์ ๋ฒํผ์ ํด๋ฆญํ์ ๋์๋ ๋ง์ง๋ง ์์
์ด ์ฌ์๋๋๋ก ์์
ํด ์ฃผ์์ต๋๋ค.
ํํธ, ๋ค์ ๋ฒํผ์ ํด๋ฆญํ์ ๋์๋ ๋ค์ ์์
์ด ์ฌ์๋๋๋ก ํ๊ณ ,
๋ง์ง๋ง ์์
์์ ๋ฒํผ์ ํด๋ฆญํ์ ๋์๋ ์ฒซ๋ฒ์งธ ์์
์ด ์ฌ์๋๋๋ก ์์
ํด ์ฃผ์์ต๋๋ค.
์ดํ, loadMusic ํจ์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ์กํด ์ฃผ๊ณ , ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
2-6. ๋ณผ๋ฅจ ์กฐ์ ๋ฒํผ ์์ ํ๊ธฐ
musicVolDown.addEventListener("click", () => {
musicAudio.volume -= 0.1;
document.querySelector(".volume .nowvolume").innerHTML = Math.round(musicAudio.volume * 10);
})
musicVolUp.addEventListener("click", () => {
musicAudio.volume += 0.1;
document.querySelector(".volume .nowvolume").innerHTML = Math.round(musicAudio.volume * 10);
})
๋ณผ๋ฅจ์ ์กฐ์ ํ ์ ์๋ ๋ฒํผ๋ ๋ง๋ค์ด ์ค๋๋ค. ์๋ ์ค์ด๊ธฐ, ๋์ด๊ธฐ ๋ฒํผ์ ํด๋ฆญํ ๋๋ง๋ค 0.1์ฉ ๋ณผ๋ฅจ์ด ์์์ง๋๋ก ์์ ํด ์ค๋๋ค. ๊ฐ์ ์ ์๋ก ์ถ๋ ฅํ๊ธฐ ์ํด 10์ ๊ณฑํด ์ฃผ์์ต๋๋ค.
2-7. ๋ฐ๋ณต ๋ฒํผ ์์ ํ๊ธฐ
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;
}
});
์ด๋ฒ์๋ ๋ฐ๋ณต ๋ฒํผ์ ๋๋ค. ๋ฐ๋ณต ๋ฒํผ์ default๋ ์ ์ฒด ๋ฐ๋ณต์ ๋๋ค. ์ ์ฒด ๋ฐ๋ณต ๋ฒํผ์ ํด๋ฆญํ๋ฉด ํ๊ณก ๋ฐ๋ณต ๋ฒํผ, ํ๊ณก ๋ฐ๋ณต ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋๋ค ๋ฐ๋ณต ๋ฒํผ, ๋๋ค ๋ฐ๋ณต ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ค์ ์ ์ฒด ๋ฐ๋ณต ๋ฒํผ์ด ๋ํ๋๋๋ก ์์ ํด ์ฃผ์์ต๋๋ค.
2-8. ์งํ๋ฐ ์์ ํ๊ธฐ
musicAudio.addEventListener("timeupdate", (e) => {
const currentTime = e.target.currentTime;
const duration = e.target.duration;
let progressWidth = (currentTime / duration) * 100;
musicProgressBar.style.width = `${progressWidth}%`;
์์ ์ ์งํ ์ํ๋ฅผ ๋ํ๋ด๋ ๋ฐ๋ฅผ ์์ ํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. timeupdate ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค. currentTime์ ์ค๋์ค์ ์งํ ์๊ฐ, duration์ ์ค๋์ค์ ์ด ๊ธธ์ด๋ฅผ ์๋ฏธํฉ๋๋ค. 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}`; // ์ด๊ฐ 10๋ณด๋ค ์์ผ๋ฉด 0์ ๋ถ์ฌ์ ๋ ์๋ฆฌ์๋ก ๋ง๋ค์ด์ค ex) 01, 02...
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}`;
});
lodeddata๋ ์ค๋์ค ์ด๋ฒคํธ๋ก, ๋ฏธ๋์ด์ ํ์ฌ ์ฌ์ ์์น์ ์๋ ํ๋ ์์ด ๋ก๋๋ฅผ ์๋ฃํ๋ฉด ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค. ์ค๋์ค์ ์ฌ์ ์๊ฐ์ ๊ตฌํ๋ค๋ฉด, innerText๋ก ์ถ๋ ฅํด ์ค๋๋ค.
musicProgress.addEventListener("click", (e) => {
let progressWidth = musicProgress.clientWidth; // ์งํ๋ฐ ์ ์ฒด ๊ธธ์ด
let clickedOffsetX = e.offsetX; // ์งํ๋ฐ ๊ธฐ์ค ์ธก์ ๋๋ x ์ขํ๊ฐ
let songDuration = musicAudio.duration; // ์ค๋์ค ์ ์ฒด ๊ธธ์ด
musicAudio.currentTime = (clickedOffsetX / progressWidth) * songDuration;
// ๋ฐฑ๋ถ์๋ก ๋๋ ์ซ์์ ๋ค์ ์ ์ฒด ๊ธธ์ด๋ฅผ ๊ณฑํด์ ํ์ฌ ์ฌ์๊ฐ์ผ๋ก ๋ฐ๊ฟ
});
์งํ๋ฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ธก์ ๋๋ x ์ขํ๊ฐ์ ๊ตฌํ ๋ค, ์งํ๋ฐ๋ฅผ ํด๋ฆญํ๋ฉด ํด๋นํ๋ ๋ถ๋ถ์ ์ฌ์ํ๋๋ก
ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
์ด ๋, ๋ณดํต ํจ์ ์์์ ์๊ธฐ ์์ ์ ๋ค์ ๊ฐ๋ฆฌํฌ ๋๋ this๋ฅผ ์ฌ์ฉํ์ง๋ง, ํ์ดํ ํจ์์์๋ this๋ฅผ
์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ musicProgress๋ฅผ ๊ทธ๋๋ก ์ ํํด ์ฃผ์ด์ผ ํฉ๋๋ค.
2-9. ended ์ด๋ฒคํธ ์์ ํ๊ธฐ
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(musicIndex); // ๋๋ค ์ธ๋ฑ์ค๊ฐ ๋ฐ์๋ ํ์ฌ ์ธ๋ฑ์ค ๊ฐ์ผ๋ก ์์
์ ๋ค์ ๋ก๋
playMusic(); // ๋ก๋ํ ์์
์ ์ฌ์
break;
}
playListMusic(); // ์ฌ์๋ชฉ๋ก ์
๋ฐ์ดํธ
});
ํ ์์
์ด ๋๋ฌ์ ๋์ ์ด๋ฒคํธ๋ฅผ ์์
ํด ์ค๋๋ค. 2-7์ ๋ฐ๋ณต ๋ฒํผ๊ณผ ์ด์ด์ง๋๋ค. getAttribute๋ก ํ์ฌ
๋ฒํผ(์ ์ฒด ๋ฐ๋ณต, ํ๊ณก ๋ฐ๋ณต, ๋๋ค ๋ฐ๋ณต)์ ํ์ธํ๊ณ , ์ฌ์ฉ์๊ฐ ์ ํํ ๋ฐ๋ณต ๋ฐฉ์์ ๋ง์ถ์ด ๋ค์ ์ธ๋ฑ์ค๋ก ๋์ด๊ฐ๋๋ค.
์ฐธ๊ณ ๋ก, while๋ฌธ๊ณผ do while๋ฌธ์ ์ฐจ์ด๋, while๋ฌธ์ ๋ฌด์กฐ๊ฑด ํ ๋ฒ์ ์คํํ๊ณ , do while๋ฌธ์ ์กฐ๊ฑด์ ๋ง์ ๋๋ง
์คํ์ํจ๋ค๋ ๊ฒ์
๋๋ค.
2-10. ๋ฎค์ง ๋ฆฌ์คํธ ์์ ํ๊ธฐ
musicListBtn.addEventListener("click", () => {
musicList.classList.add("show");
});
musicListCloseBtn.addEventListener("click", () => {
musicList.classList.remove("show");
});
๋ง์ง๋ง์ผ๋ก, ๋ฎค์ง ๋ฆฌ์คํธ๋ฅผ ์์ ํด ๋ด ์๋ค. ์ฐ์ , ๋ฎค์ง ๋ฆฌ์คํธ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ฎค์ง ๋ฆฌ์คํธ๊ฐ ๋ํ๋๊ณ , ๋ซ๊ธฐ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ฎค์ง ๋ฆฌ์คํธ๊ฐ ์จ๊ฒจ์ง๋๋ก ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
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.insertAdjacentHTML("beforeend", li);
for๋ฌธ์ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์์ ๋ค์ ๋ฎค์ง ๋ฆฌ์คํธ์ ์ถ๊ฐํด ์ค๋๋ค. beforeend๋ element ์์ ๊ฐ์ฅ ๋ง์ง๋ง child๋ก ์ถ๊ฐํ๋ผ๋ ์๋ฏธ์ ๋๋ค.
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}`); // ์์ฑ์ ์ค๋์ค ๊ธธ์ด ๊ธฐ๋ก
});
}
๋ฆฌ์คํธ์ ์ฌ์ ์๊ฐ๋ ๋ถ๋ฌ์ ์ค๋๋ค. ์ค๋์ค์ loadeddata ์ด๋ฒคํธ๋ฅผ ์ค์ ํ๊ณ , 2-8๊ณผ ๊ฐ์ด ์ฌ์ ์๊ฐ์ ์ถ๋ ฅํด ์ค๋๋ค.
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"); // ํด๋์ค playing ์ถ๊ฐ
audioTag.innerText = "Playing" // ์ฌ์์ค์ธ ์์
์ ๋ฉํธ ์ถ๊ฐ
}
musicListAll[i].setAttribute("onclick", "clicked(this)");
}
}
์ด์ , ๋ฆฌ์คํธ์ ์๋ ์์
์ ํด๋ฆญํ๋ฉด ํด๋น ์์
์ด ์ฌ์๋๋๋ก ์์
ํด ๋ด
์๋ค.
์ ๊ณผ์ ์ ์์
์ ํด๋ฆญํ๋ฉด playing ํด๋์ค๋ฅผ ์ถ๊ฐํ๊ณ , ๋ฎค์ง ๋ฆฌ์คํธ์์
์ฌ์ ์๊ฐ ๋์ ๋ฉํธ๋ฅผ ์ถ๋ ฅํ๋๋ก ๋ง๋๋ ๊ณผ์ ์
๋๋ค.
๊ฐ๊ฐ์ ์์
์ ํด๋ฆญํ๋ฉด clicked ํจ์๊ฐ ์คํ๋๋๋ก ์์
ํด ์ค๋๋ค.
function clicked(el){
let getLiIndex = el.getAttribute("data-index"); // ํด๋ฆญํ ๋ฆฌ์คํธ์ ์ธ๋ฑ์ค๊ฐ ์ ์ฅ
musicIndex = getLiIndex; // ํด๋ฆญํ ์ธ๋ฑ์ค๊ฐ์ ๋ฎค์ง ์ธ๋ฑ์ค์ ์ ์ฅ
loadMusic(musicIndex); // ํด๋น ์ธ๋ฑ์ค ๋ฎค์ง์ ๋ก๋
playMusic(); // ์์
์ฌ์
playListMusic(); // ์์
๋ฆฌ์คํธ ์
๋ฐ์ดํธ
}
์์ ์ ํด๋ฆญํ์ ๋ ์คํ๋๋ clicked ํจ์๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
2-11. ํจ์ ์คํ์ํค๊ธฐ
window.addEventListener("load", () => {
loadMusic(musicIndex);
playListMusic();
});
์ด์ , ์์ ์ ์ฌ์ํ๋ loadMusic(), ๋ฆฌ์คํธ๋ฅผ ์ด๊ธฐํํ๋ playListMusic() ํจ์๋ฅผ ์คํ์์ผ์ฃผ๋ฉด ๋์ ๋๋ค.
๊ฒฐ๊ณผ
'Javascript Effect' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์๋ฐ์คํฌ๋ฆฝํธ : ๊ฒ์ ํจ๊ณผ : ๊ฒ์ ๊ฒ์ (1) | 2022.10.24 |
---|---|
์๋ฐ์คํฌ๋ฆฝํธ : ์ฌ๋ผ์ด๋ ํจ๊ณผ : ๋ฒํผ, ๋ท๋ฉ๋ด (1) | 2022.10.18 |
์๋ฐ์คํฌ๋ฆฝํธ : ๊ฒ์ ํจ๊ณผ : sort(), reverse() (0) | 2022.10.18 |
์๋ฐ์คํฌ๋ฆฝํธ ํจ๋ด๋์ค ํจ๊ณผ : ๋ฆฌ๋น ํจ๊ณผ (4) | 2022.10.09 |
์๋ฐ์คํฌ๋ฆฝํธ ๊ฒ์ ํจ๊ณผ : filter() (4) | 2022.09.29 |
๋๊ธ