반응형
실 판매사이트 제작에 사용된 오디오 비주얼라이저 플레이어 입니다.
실적용 예제
https://d.cafe24.com/product/product_detail?productCode=PTWD836035
audio.html
<!DOCTYPE html>
<html lang="ko" >
<head>
<meta charset="UTF-8">
<title>Smart Web - Audio visualizer continuous play</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="music-player music-active-js">
<canvas class="opacity-js" id="myCanvas" width="800" height="400"></canvas>
<audio crossorigin="anonymous" id="myAudio"></audio>
<div class="music-player-element icon-circle-mid">
<img src="https://i.ibb.co/dKbwbMV/circle.png" alt="">
<div class="music-name"></div>
<div class="next-prev-arrows">
<div class="music-prev">
<img src="https://i.ibb.co/Svgdrz3/music-prev.png" alt="">
</div>
<div class="music-stop">
<img src="https://i.ibb.co/wYdY2jx/music-stop.png" alt="">
</div>
<div class="music-next">
<img src="https://i.ibb.co/Q6fXNGX/music-next.png" alt="">
</div>
</div>
</div>
<div class="music-player-element icon-play-pause play">
<img src="https://i.ibb.co/MBFjvcj/play.png" alt="">
</div>
<div class="music-arrow-left">
<img src="https://i.ibb.co/pd4Jgcq/line-left.png" alt="">
</div>
<div class="music-arrow-right">
<img src="https://i.ibb.co/qBYnqf7/line-right.png" alt="">
</div>
</div>
<div class="song-selection">
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
</div>
<script src="./script.js"></script>
</body>
</html>
script.js
let canvas = document.getElementById("myCanvas");
let audio = document.getElementById("myAudio");
audio.crossOrigin = "anonymous";
// 오디오 소스
// 오디오 컨텍스트 생성
// let audioCtx = new AudioContext() || new webkitAudioContext(); -- for safari
let audioCtx = new AudioContext();
// 분석기가 작업할 수 있도록 오디오 노드를 만듭니다.
let source = audioCtx.createMediaElementSource(audio);
// 분석기 만들기
let analyser = audioCtx.createAnalyser();
// 2D 컨텍스트 만들기
let ctx = canvas.getContext("2d");
// 연결하기
source.connect(analyser);
source.connect(audioCtx.destination);
// analyser.fftSize = 2048;
analyser.smoothingTimeConstant = 0.6;
analyser.fftSize = 512;
// 버퍼 길이
let bufferLength = analyser.frequencyBinCount;
let data = new Uint8Array(bufferLength);
// 그리기 기능
function draw(data) {
let gradient = ctx.createLinearGradient(0, 0, 0, 300);
gradient.addColorStop(1, "#ff0033");
ctx.fillStyle = gradient;
ctx.shadowBlur = 20;
ctx.shadowColor = "#ffffff";
let cx = canvas.width / 2;
let cy = canvas.height / 2;
let radius = 140;
let barWidth = 2;
let barHeight = 2;
let barSpacing = 7;
let maxBarNum = Math.floor((radius * 2 * Math.PI) / (barWidth + barSpacing));
let slicedPercent = Math.floor((maxBarNum * 25) / 100);
let barNum = maxBarNum - slicedPercent;
let freqJump = Math.floor(data.length / maxBarNum);
for (let i = 0; i < barNum; i++) {
let amplitude = data[i * freqJump];
let alfa = (i * 2 * Math.PI) / maxBarNum;
let beta = ((3 * 45 - barWidth) * Math.PI) / 280;
let x = 0;
let y = radius - (amplitude / 12 - barHeight);
let w = barWidth;
let h = amplitude / 6 + barHeight;
ctx.save();
ctx.translate(cx + barSpacing, cy + barSpacing);
ctx.rotate(alfa - beta);
ctx.fillRect(x, y, w, h);
ctx.restore();
}
}
// 루프 기능
function loopingFunction() {
requestAnimationFrame(loopingFunction);
analyser.getByteFrequencyData(data);
ctx.clearRect(0, 0, canvas.width, canvas.height);
draw(data);
}
loopingFunction();
// 음악 재생
let play = document.querySelector(".play");
let musicIcon = document.querySelector(".icon-play-pause img");
function playMusic() {
audioCtx.resume();
canvas.classList.remove("opacity-js");
if (audio.paused) {
audio.play();
musicIcon.src = "https://i.ibb.co/2hWV9L6/pause.png";
} else {
audio.pause();
musicIcon.src = "https://i.ibb.co/MBFjvcj/play.png";
}
}
play.addEventListener("click", playMusic);
// 음악 중지
let stop = document.querySelector(".music-stop");
function stopMusic() {
audio.pause();
audio.currentTime = 0;
musicIcon.src = "https://i.ibb.co/MBFjvcj/play.png";
}
stop.addEventListener("click", stopMusic);
// 로드 트랙 기능
let songs = document.querySelectorAll(".song-select");
let songArr = [];
songs.forEach(function (song) {
songArr.push({
songName: song.dataset.name,
songAuthor: song.dataset.author,
songPath: song.dataset.path
});
});
let musicName = document.querySelector(".music-name");
let counter = 0;
let maxSongs = songArr.length;
function loadMusic(counter) {
audio.src = `${songArr[counter].songPath}`;
audio.load();
musicName.textContent = `${songArr[counter].songAuthor} - ${songArr[counter].songName}`;
}
loadMusic(counter);
// 다음 및 이전 노래
let next = document.querySelector(".music-next");
let prev = document.querySelector(".music-prev");
next.addEventListener("click", function () {
if (counter < maxSongs - 1) {
counter++;
loadMusic(counter);
} else {
counter = 0;
loadMusic(counter);
}
playMusic();
});
prev.addEventListener("click", function () {
if (counter > 0) {
counter--;
loadMusic(counter);
} else {
if (counter === 0) counter = maxSongs;
counter--;
loadMusic(counter);
}
playMusic();
});
// 음악종료
audio.addEventListener("ended", function () {
if (counter < maxSongs - 1) {
counter++;
} else {
counter = 0;
}
loadMusic(counter);
playMusic();// 다음 곡을 로드하고 재생합니다.
});
style.css
* {
padding: 0;
margin: 0;
-webkit-tap-highlight-color :transparent;
}
.music-player {
background: #0e0929;
color: white;
position: relative;
top: 0%;
left: 0%;
width: 100vw;
height: 100vh;
z-index: 5;
transition: 0.2s;
overflow: hidden;
}
.music-player #myAudio {
position: relative;
z-index: 55;
}
.music-player #myCanvas {
position: absolute;
top: 48%;
left: 49.5%;
transform: translate(-50%, -50%);
transition: 0.2s;
}
.music-player .music-player-element {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.music-player .icon-circle-mid {
width: 556px;
height: 556px;
}
.music-player .icon-circle-mid .music-name {
position: absolute;
top: 7%;
left: 58%;
font-family: monospace;
font-size: 14px;
}
.music-player .icon-circle-mid .next-prev-arrows {
position: absolute;
top: 15%;
left: 70%;
display: flex;
width: 110px;
justify-content: space-around;
align-items: center;
z-index: 11;
}
.music-player .icon-circle-mid .next-prev-arrows div {
cursor: pointer;
}
.music-player .icon-play-pause {
width: 162px;
height: 162px;
cursor: pointer;
z-index: 5;
}
.music-player .music-arrow-left,
.music-player .music-arrow-right {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 200px;
}
.music-player .music-arrow-left {
left: 0;
}
.music-player .music-arrow-right {
right: 0;
}
.opacity-js {
opacity: 0;
}
@media only screen and (max-width: 850px) {
.music-arrow-left,
.music-arrow-right {
display: none;
}
}
@media only screen and (max-width: 500px) {
.music-player .icon-circle-mid img {
transform: scale(0.6);
}
.music-player .icon-circle-mid .next-prev-arrows {
top: 32%;
left: 55%;
}
.music-player .icon-circle-mid .music-name {
top: 24%;
left: 55%;
font-size:12px;
width: 170px;
}
}
@media (min-width: 560px) and (max-height: 480px) and (orientation: landscape) {
.music-player .icon-circle-mid {
width: auto;
height: auto;
}
.music-player .icon-circle-mid .music-name {
top: 8%;
}
.music-player .icon-circle-mid .next-prev-arrows {
top: 22%;
left: 75%;
}
.music-player .music-arrow-left,
.music-player .music-arrow-right {
display: none;
}
}
반응형
'디자인소스' 카테고리의 다른 글
웹표준 마크업을 사용한 깔끔한 사이트 맵 (1) | 2024.11.22 |
---|---|
깔끔한 이미지 슬라이드쇼 애니메이션 (0) | 2024.11.18 |
CSS3 로 구성된 간단한 시계 소스 (0) | 2024.11.12 |
이미지 필터 생성기 (0) | 2024.11.01 |
mp3 음악입자 그래픽 이퀄라이저 시각화 플레이어 가사자막 생성기 (2) | 2024.09.10 |
반응형 G5 BEST (2) | 2024.06.02 |
워드프레서 와 G5 기반 미디어 홈제작 (0) | 2024.05.23 |
스마트 웹 사이트 디자인 동영상 슬라이드 메뉴 (0) | 2023.12.13 |
댓글