user-img

๋‚ด ํ™ˆ์—์„œ ์‚ฌ์šฉ์ค‘์ธ ๋ฎค์ง ํ”Œ๋ ˆ์ด์–ด

๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ๋กœ ์ด๋™ ๊ฐ€๋Šฅ / ์žฌ์ƒ์ค‘์ธ ์Œ์•… ๋Š๊ธฐ์ง€ ์•Š์Œ / ๋ชจ๋ฐ”์ผ ์ง€์›

 

css ์ˆ˜์ • ๋””์ž์ธ ์ถ”๊ฐ€ ๋ฐ ํŽธ์ง‘ ๋ง˜๋Œ€๋ฃจ ํ•˜์„ธ์š” ์ €๋„ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๊บผ ๋ณด๊ณ  ์ฐธ๊ณ ํ•ด์„œ ๋งŒ๋“ ๊ฑฐ๊ธฐ ๋•Œ๋ฌธ์—...

 

See the Pen Untitled by 123 (@123-the-scripter) on CodePen.

 

์ดˆ๋ณด์ž๋ฅผ ์œ„ํ•œ ๋ณต๋ถ™ ๊ฐ€์ด๋“œ

HTML

ํ•ด๋‹น ์ฝ”๋“œ๋ธ”๋Ÿญ ๋‚ด์šฉ์ „์ฒด๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ํ‹ฐ์Šคํ† ๋ฆฌ ์Šคํ‚จ ํŽธ์ง‘ > htmlํŽธ์ง‘ ํด๋ฆญ > ๋นˆ ๊ณณ ์•„๋ฌด๋ฐ๋‚˜ (๋งจ ์•„๋ž˜ ์ถ”์ฒœ) ๋ถ™์—ฌ๋„ฃ๊ธฐ 

์ด๊ฒƒ๋งŒ ์ ์šฉํ•˜์‹œ๋ฉด ๋ชป์ƒ๊ธด๊ฒŒ ๋– ๋‹ค๋‹™๋‹ˆ๋‹ค ์•„๋ž˜ CSS๊นŒ์ง€ ์ ์šฉํ•ด์•ผ ๋ฉ๋‹ˆ๋‹ค

 

** 'song1.mp3', 'song2.mp3', 'song3.mp3' ์ด์ž๋ฆฌ์— ํ™•์žฅ์ž๋ช… .mp3์ธ ํŒŒ์ผ์„ ์ง‘์–ด๋„ฃ์œผ๋ฉด ์žฌ์ƒ๋ฉ๋‹ˆ๋‹ค

ํ‹ฐ์Šคํ† ๋ฆฌ ๊ธ€์“ฐ๊ธฐ > ๋„ฃ๊ณ ์‹ถ์€ ์Œ์› ํŒŒ์ผ mp3ํŒŒ์ผ ์‚ฝ์ž… > ํ•ด๋‹น ํŒŒ์ผ์˜ ๋งํฌ ๋ณต์‚ฌ > songN.mp3 ์ž๋ฆฌ์— ๋ถ™์—ฌ๋„ฃ๊ธฐ

<!-- MP3 Player -->
<div class="mp3-player" id="music-player">
    <button class="mp3-player-btn" id="prev">|โ—</button>
    <button class="mp3-player-btn" id="play-pause">โ–ถ</button>
    <button class="mp3-player-btn" id="next">โ–ท|</button>
</div>

<!-- MP3 Player JavaScript -->
<script>
    const audioFiles = [
        'song1.mp3',
        'song2.mp3',
        'song3.mp3'
    ];

    let currentTrackIndex = parseInt(localStorage.getItem('currentTrackIndex')) || 0;
    let isPlaying = localStorage.getItem('isPlaying') === 'true';

    const audio = new Audio(audioFiles[currentTrackIndex]);

    if (isPlaying) {
        audio.play().catch(() => {
            console.log('Auto-play blocked by browser policy.');
        });
    }

    const playPauseButton = document.getElementById('play-pause');
    const prevButton = document.getElementById('prev');
    const nextButton = document.getElementById('next');
    const musicPlayer = document.getElementById('music-player');

    const updatePlayPauseButton = () => {
        playPauseButton.textContent = isPlaying ? 'โšโš' : 'โ–ถ';
    };

    const playTrack = () => {
        audio.play().then(() => {
            isPlaying = true;
            localStorage.setItem('isPlaying', 'true');
            updatePlayPauseButton();
        }).catch((err) => {
            console.error('Playback failed:', err);
        });
    };

    const pauseTrack = () => {
        audio.pause();
        isPlaying = false;
        localStorage.setItem('isPlaying', 'false');
        updatePlayPauseButton();
    };

    const switchTrack = (index) => {
        audio.pause();
        currentTrackIndex = (index + audioFiles.length) % audioFiles.length;
        localStorage.setItem('currentTrackIndex', currentTrackIndex);
        audio.src = audioFiles[currentTrackIndex];
        if (isPlaying) {
            audio.play().catch(() => {
                console.log('Auto-play blocked.');
            });
        }
    };

    playPauseButton.addEventListener('click', () => {
        isPlaying ? pauseTrack() : playTrack();
    });

    prevButton.addEventListener('click', () => {
        switchTrack(currentTrackIndex - 1);
    });

    nextButton.addEventListener('click', () => {
        switchTrack(currentTrackIndex + 1);
    });

    updatePlayPauseButton();

    // ์ด์ „ ์žฌ์ƒ ์‹œ๊ฐ„ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
    window.addEventListener('beforeunload', () => {
        localStorage.setItem('currentTime', audio.currentTime);
    });

    const savedTime = localStorage.getItem('currentTime');
    if (savedTime) audio.currentTime = parseFloat(savedTime);

    // ๋“œ๋ž˜๊ทธ ๊ธฐ๋Šฅ
    let isDragging = false;
    let offsetX, offsetY;

    const savePlayerPosition = () => {
        const rect = musicPlayer.getBoundingClientRect();
        localStorage.setItem('playerPosition', JSON.stringify({ top: rect.top, left: rect.left }));
    };

    const loadPlayerPosition = () => {
        const position = JSON.parse(localStorage.getItem('playerPosition'));
        if (position) {
            musicPlayer.style.top = `${position.top}px`;
            musicPlayer.style.left = `${position.left}px`;
            musicPlayer.style.right = 'auto';
            musicPlayer.style.bottom = 'auto';
        }
    };

    musicPlayer.addEventListener('mousedown', (e) => {
        isDragging = true;
        offsetX = e.clientX - musicPlayer.getBoundingClientRect().left;
        offsetY = e.clientY - musicPlayer.getBoundingClientRect().top;
    });

    document.addEventListener('mousemove', (e) => {
        if (isDragging) {
            musicPlayer.style.left = `${e.clientX - offsetX}px`;
            musicPlayer.style.top = `${e.clientY - offsetY}px`;
            musicPlayer.style.right = 'auto';
            musicPlayer.style.bottom = 'auto';
        }
    });

    document.addEventListener('mouseup', () => {
        if (isDragging) {
            isDragging = false;
            savePlayerPosition();
        }
    });

    loadPlayerPosition();
</script>

 

CSS

ํ•ด๋‹น ์ฝ”๋“œ๋ธ”๋Ÿญ ๋‚ด์šฉ์ „์ฒด๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ํ‹ฐ์Šคํ† ๋ฆฌ ์Šคํ‚จ ํŽธ์ง‘ > htmlํŽธ์ง‘ ํด๋ฆญ > ์ตœ์ƒ๋‹จ์˜ CSS ํด๋ฆญ > ๋นˆ ๊ณณ ์•„๋ฌด๋ฐ๋‚˜ (๋งจ ์•„๋ž˜ ์ถ”์ฒœ) ๋ถ™์—ฌ๋„ฃ๊ธฐ 

 

์‰ฝ๊ฒŒ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ์š”์†Œ

  1. .mp3-player์˜ height (ํ”Œ๋ ˆ์ด์–ด ๋ฐ•์Šค ๋†’์ด) width (ํ”Œ๋ ˆ์ด์–ด ๋ฐ•์Šค ๋„“์ด)
  2.  mp3-player์˜ background-color(ํ”Œ๋ ˆ์ด์–ด ๋ฐ•์Šค ์ƒ‰์ƒ) : html ์ƒ‰์ƒ์ฝ”๋“œ ์‚ฌ์ดํŠธ์—์„œ ์›ํ•˜๋Š” ์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ 
  3.  mp3-player์˜ box-shadow (๊ทธ๋ฆผ์ž ์„ค์ •) : rgb๊ฐ’ ์กฐ์ ˆํ•˜์—ฌ ์ƒ‰์ƒ ๋ณ€๊ฒฝ + ํˆฌ๋ช…๋„ ์กฐ์ ˆ ๊ฐ€๋Šฅ
  4.  mp3-player button์˜ font-size(์žฌ์ƒ/์ผ์‹œ์ •์ง€ ๋’ค๋กœ๊ฐ€๊ธฐ ์•ž์œผ๋กœ๊ฐ€๊ธฐ ํฌ๊ธฐ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ)
  5.  mp3-player button:hover์˜ color(๋งˆ์šฐ์Šค ์˜ฌ๋ ธ์„ ๋•Œ ๋ฒ„ํŠผ ์ƒ‰์ƒ ๋ณ€ํ™”)
.mp3-player {
    position: fixed;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 10px;
    height: 40px;
    width: 120px;
    border-radius: 10px;
    background-color: #f0f0f0;
    box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
    z-index: 9999;
    cursor: grab;
}

.mp3-player:active {
    cursor: grabbing;
}

.mp3-player button {
    background: none;
    border: none;
    font-size: 15px;
    cursor: pointer;
}

.mp3-player button:focus {
    outline: none;
}

.mp3-player button:hover {
    color: #ccc;
}

 

CSS๋ฅผ <style>๋กœ ๋ฌถ์–ด์„œ html์— ํ•œ๋ฒˆ์— ์ง‘์–ด๋„ฃ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋Š”๋ฐ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์„ค์ •๊ฐ’์ด em์ธ ์• ๋“ค์˜ ํฌ๊ธฐ๊ฐ€ ๋“ค์‘ฅ๋‚ ์‘ฅํ•ด์ง€๋”๋ผ๊ณ ์š” ๊ทธ๋ž˜๋„ ๋‚˜๋Š” ์–ด๋ ค์›Œ์„œ ๋ชปํ•˜๊ฒ ๋‹ค ํ•˜์‹œ๋Š” ๋ถ„๋“ค์„ ์œ„ํ•ด HTML ํ†ตํ•ฉ ์ฝ”๋“œ๋„ ๋‹ฌ์•„๋†“์Šต๋‹ˆ๋‹ค 

HTML ํ†ตํ•ฉ
<div id="music-player-wrapper">
    <div class="mp3-player" id="music-player">
        <button class="mp3-player-btn" id="prev">|โ—</button>
        <button class="mp3-player-btn" id="play-pause">โ–ถ</button>
        <button class="mp3-player-btn" id="next">โ–ท|</button>
    </div>
</div>

<style>
    .mp3-player {
    position: fixed;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 10px;
    height: 40px;
    width: 120px;
    border-radius: 10px;
    background-color: #f0f0f0;
    box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
    z-index: 9999;
    cursor: grab;
    }

    .mp3-player:active {
        cursor: grabbing;
    }

    .mp3-player button {
        background: none;
        border: none;
        font-size: 15px;
        cursor: pointer;
    }

    .mp3-player button:focus {
        outline: none;
    }

    .mp3-player button:hover {
        color: #ccc;
    }
</style>

<!-- MP3 Player JavaScript -->
<script>
    const audioFiles = [
        'song1.mp3',
        'song2.mp3',
        'song3.mp3'
    ];

    let currentTrackIndex = parseInt(localStorage.getItem('currentTrackIndex')) || 0;
    let isPlaying = localStorage.getItem('isPlaying') === 'true';

    const audio = new Audio(audioFiles[currentTrackIndex]);

    if (isPlaying) {
        audio.play().catch(() => {
            console.log('Auto-play blocked by browser policy.');
        });
    }

    const playPauseButton = document.getElementById('play-pause');
    const prevButton = document.getElementById('prev');
    const nextButton = document.getElementById('next');
    const musicPlayer = document.getElementById('music-player');

    const updatePlayPauseButton = () => {
        playPauseButton.textContent = isPlaying ? 'โšโš' : 'โ–ถ';
    };

    const playTrack = () => {
        audio.play().then(() => {
            isPlaying = true;
            localStorage.setItem('isPlaying', 'true');
            updatePlayPauseButton();
        }).catch((err) => {
            console.error('Playback failed:', err);
        });
    };

    const pauseTrack = () => {
        audio.pause();
        isPlaying = false;
        localStorage.setItem('isPlaying', 'false');
        updatePlayPauseButton();
    };

    const switchTrack = (index) => {
        audio.pause();
        currentTrackIndex = (index + audioFiles.length) % audioFiles.length;
        localStorage.setItem('currentTrackIndex', currentTrackIndex);
        audio.src = audioFiles[currentTrackIndex];
        if (isPlaying) {
            audio.play().catch(() => {
                console.log('Auto-play blocked.');
            });
        }
    };

    playPauseButton.addEventListener('click', () => {
        isPlaying ? pauseTrack() : playTrack();
    });

    prevButton.addEventListener('click', () => {
        switchTrack(currentTrackIndex - 1);
    });

    nextButton.addEventListener('click', () => {
        switchTrack(currentTrackIndex + 1);
    });

    updatePlayPauseButton();

    // ์ด์ „ ์žฌ์ƒ ์‹œ๊ฐ„ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
    window.addEventListener('beforeunload', () => {
        localStorage.setItem('currentTime', audio.currentTime);
    });

    const savedTime = localStorage.getItem('currentTime');
    if (savedTime) audio.currentTime = parseFloat(savedTime);

    // ๋“œ๋ž˜๊ทธ ๊ธฐ๋Šฅ
    let isDragging = false;
    let offsetX, offsetY;

    const savePlayerPosition = () => {
        const rect = musicPlayer.getBoundingClientRect();
        localStorage.setItem('playerPosition', JSON.stringify({ top: rect.top, left: rect.left }));
    };

    const loadPlayerPosition = () => {
        const position = JSON.parse(localStorage.getItem('playerPosition'));
        if (position) {
            musicPlayer.style.top = `${position.top}px`;
            musicPlayer.style.left = `${position.left}px`;
            musicPlayer.style.right = 'auto';
            musicPlayer.style.bottom = 'auto';
        }
    };

    musicPlayer.addEventListener('mousedown', (e) => {
        isDragging = true;
        offsetX = e.clientX - musicPlayer.getBoundingClientRect().left;
        offsetY = e.clientY - musicPlayer.getBoundingClientRect().top;
    });

    document.addEventListener('mousemove', (e) => {
        if (isDragging) {
            musicPlayer.style.left = `${e.clientX - offsetX}px`;
            musicPlayer.style.top = `${e.clientY - offsetY}px`;
            musicPlayer.style.right = 'auto';
            musicPlayer.style.bottom = 'auto';
        }
    });

    document.addEventListener('mouseup', () => {
        if (isDragging) {
            isDragging = false;
            savePlayerPosition();
        }
    });

    loadPlayerPosition();
</script>

 

 

ํ˜„์žฌ๊ธ€
๋“œ๋ž˜๊ทธ ์ด๋™ ๊ฐ€๋Šฅํ•œ ํ”Œ๋กœํŒ… ์˜ค๋””์˜ค ํ”Œ๋ ˆ์ด์–ด