Code trình phát nhạc có thể sử dụng cho bất kỳ dự án thiết kế nào của bạn. Bạn có thể sử dụng để người dùng tải nhạc lên để phát trực tiếp. Nếu bạn có ý tưởng tốt hơn có thể kết nối với các thư viện nhạc có sẵn để người dùng phát nhạc để nghe ngay lập tức.
Code trình phát nhạc có thể tuỳ chỉnh các hiệu ứng rất đẹp từ màu sắc, kích thước và nhiều thứ khác. Bạn có thể chỉnh sửa trong phần Code để thay đổi các thuộc tính theo nhu cầu của mình.
Code trình phát nhạc cho người dùng
Đầu tiên, Blog Lại Văn Đức mời bạn cùng xem demo hiển thị cho bộ code này. Bạn sẽ cần có bài hát định dạng MP3 trên máy vi tính hoặc điện thoại trước. Sau đó hãy nhấp vào Chọn Tệp để tải bài hết lên để nghe.
Bộ code này sẽ không tải file nhạc của bạn lên máy chủ lưu trữ code. Nó chỉ sử dụng để phát chính file nhạc bạn chọn.
Chia sẻ Code trình phát nhạc chi tiết
Đầu tiên, bạn cần gọi file js này về trước.
<script src='http://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js'></script>
Tiếp theo là Code HTML để làm khung cho ứng dụng phát nhạc này.
.musicControls input.audiofile(type='file') //- button.listenButton ...or listen to one of mine // Silly CORS button.playPauseButton ▶ i#loading Chọn một file âm thanh... // This should match the values in the js - var maxSideNum = 24 - var maxRectangleNum = 24 .prism - for (var x = 0; x < maxSideNum; x++) .side.hide - for (var y = 0; y < maxRectangleNum; y++) .rectangle.hide
Tất nhiên, chúng ta không thể thiếu CSS cho bộ code trình phát nhạc.
// All of the commented out things are from the static, pre-dat.gui version that are no longer necessary //$sideNum: 12; //$rectNum: 12; //$width: 100px; //$margin: 1% * 7.3; $border: 3px solid #4DA16F; /* Default all same color */ * { box-sizing: border-box; } html, body { height:100%; } body { background: rgb(30,30,30); font-family: 'Helvatica', sans-serif; color: #FFF; position:relative; perspective: 1000px; perspective-origin: 50% 50%; } .hide { display:none; } .prism { position:absolute; //top:calc(50% - #{$width * 2}); //left:calc(50% - #{$width * 0.5}); //width:$width; //height:$width * 4; transform-style: preserve-3d; animation:rotate 8s linear infinite; display:none; } .side { width:100%; height:100%; border-top: $border; border-bottom: $border; border-color:currentColor; position:absolute; } .rectangle { //height: (100% / $rectNum) - 2%; //width:80%; //margin:10px auto; border: $border; border-color:currentColor; } .solid .rectangle { background:currentColor; } //@for $i from 1 through $sideNum { // .side:nth-child(#{$i}) { // color: hsl(144, 55%, 20% + ($i / $sideNum) * 40%); // // transform: rotateY($i * (360 / $sideNum) + deg) translateZ($width * 1.85) rotateX(180deg); // } // .side.rainbow:nth-child(#{$i}) { // color: hsl(360*($i / $sideNum), 80%, 55%); // } //} @keyframes rotate { from { transform:rotateY(0); } to { transform:rotateY(-360deg); } } .musicControls, i { position: absolute; border-radius: 5px; border: 1px solid rgba(255, 255, 255, 0.3); padding: 10px; } .musicControls { top: 20px; left: 20px; } i { left: 50%; top: 50%; transform: translateY(-50%) translateX(-50%); } body.loaded { #loading { display: none; } .prism { display:block; } }
Cuối cùng là linh hồn của bộ ứng dụng phát nhạc với JavaScript.
var maxSideNum = 24, maxRectangleNum = 24; // Dat.gui setup var Options = function() { this.height = 400; this.radius = 185; this.sideCount = 12; this.rectangleCount = 12; this.rectangleWidth = 80; this.vertMargin = 10; this.borderWidth = 3; this.color = 200; this.solidBG = false; this.rainbowMode = false; this.animateThroughSpectrum = false; }; window.onload = function() { // dat.gui setup var myOptions = new Options(), gui = new dat.GUI(), f1 = gui.addFolder('Prism Controls'), f2 = gui.addFolder('Rectangle Controls'), f3 = gui.addFolder('Color Controls'), mySideCount = f1.add(myOptions, 'sideCount', 3, maxSideNum).step(1), myRadius = f1.add(myOptions, 'radius', 30, 600).step(15), myHeight = f1.add(myOptions, 'height', 50, 750).step(50), myRectangleCount = f2.add(myOptions, 'rectangleCount', 3, maxRectangleNum).step(1), myRectangleWidth = f2.add(myOptions, 'rectangleWidth', 1, 100).step(5), myVertMargin = f2.add(myOptions, 'vertMargin', 0, 15).step(1), myBorderWidth = f2.add(myOptions, 'borderWidth', 0, 15).step(1), myColor = f3.add(myOptions, 'color', 0, 360).step(1), mySolidBG = f3.add(myOptions, 'solidBG'), myRainbow = f3.add(myOptions, 'rainbowMode'), myAnimateThroughSpectrum = f3.add(myOptions, 'animateThroughSpectrum'); f2.open(); var audio, analyser, audioctx, sourceNode, stream; var audioInput = document.querySelector('.audiofile'), listenButton = document.querySelector(".listenButton"), playPauseButton = document.querySelector(".playPauseButton"); var c = 0, // Used to change color over time paused = true; /*var myMusic = [ "https://laivanduc.vn/wp-content/uploads/2021/12/Chieu-Cuoi-Tuan-Le-Quyen.mp3", "https://laivanduc.vn/wp-content/uploads/2021/12/Chieu-Cuoi-Tuan-Le-Quyen.mp3", "https://laivanduc.vn/wp-content/uploads/2021/12/Chieu-Cuoi-Tuan-Le-Quyen.mp3", "https://laivanduc.vn/wp-content/uploads/2021/12/Chieu-Cuoi-Tuan-Le-Quyen.mp3" ];*/ var prism = document.querySelector(".prism"), sides = document.querySelectorAll(".side"), rectangleArray = [maxSideNum], lastTime = Date.now(), timeGap = 50; function rectangleSetup() { for(var i = 0; i < maxSideNum; i++) { rectangleArray[i] = sides[i].querySelectorAll(".rectangle"); } } rectangleSetup(); // dat.gui listeners // f1 listeners function sideCountChange(newCount) { [].forEach.call(sides, function(elem, i) { if(i < myOptions.sideCount) { // The circle is inscribed inside of the prism, so we can use this formula to calculate the side length var sideLength = 2 * (myOptions.radius) * Math.tan(Math.PI / newCount); prism.style.width = sideLength + "px"; prism.style.left = "calc(50% - " + sideLength / 2 + "px)"; sides[i].style.transform = "rotateY(" + i * (360 / newCount) + "deg) translateZ(" + myOptions.radius + "px) rotateX(180deg)"; sides[i].classList.remove("hide"); } else { sides[i].classList.add("hide"); } }); } mySideCount.onFinishChange(sideCountChange); sideCountChange(myOptions.sideCount); function radiusChange(newRadius) { sideCountChange(myOptions.sideCount); } myRadius.onFinishChange(radiusChange); radiusChange(myOptions.radius); function heightChange(newHeight) { prism.style.height = newHeight + "px"; prism.style.top = "calc(50% - " + newHeight / 2 + "px)" rectangleCountChange(myOptions.rectangleCount); } myHeight.onFinishChange(heightChange); heightChange(myOptions.height); // f2 listeners function rectangleCountChange(newCount) { [].forEach.call(rectangleArray, function(side, i) { [].forEach.call(side, function(rect, i) { if(i < myOptions.rectangleCount) { rect.style.height = (myOptions.height - myOptions.vertMargin) / newCount - myOptions.vertMargin + "px"; rect.classList.remove("hide"); } else { rect.classList.add("hide"); } }); }); } myRectangleCount.onFinishChange(rectangleCountChange); rectangleCountChange(myOptions.rectangleCount); function rectangleWidthChange(newWidth) { [].forEach.call(rectangleArray, function(side, i) { [].forEach.call(side, function(rect, i) { rect.style.width = newWidth + "%"; }); }); } myRectangleWidth.onFinishChange(rectangleWidthChange); rectangleWidthChange(myOptions.rectangleWidth); function vertMarginChange(newMargin) { [].forEach.call(rectangleArray, function(side, i) { [].forEach.call(side, function(rect, i) { rect.style.margin = newMargin + "px auto"; }); }); rectangleCountChange(myOptions.rectangleCount); } myVertMargin.onFinishChange(vertMarginChange); vertMarginChange(myOptions.vertMargin); function borderWidthChange(newWidth) { [].forEach.call(rectangleArray, function(side, i) { [].forEach.call(side, function(rect, i) { rect.style.borderWidth = newWidth + "px"; }); }); } myBorderWidth.onFinishChange(borderWidthChange); borderWidthChange(myOptions.borderWidthChange); // f3 listeners function colorChange(value) { if(!myOptions.rainbowMode) [].forEach.call(sides, function(elem, i) { sides[i].style.color = "hsl(" + value + ", 55%, " + (20 + (i / myOptions.sideCount) * 40) + "%)"; }); } myColor.onFinishChange(colorChange); colorChange(myOptions.color); mySolidBG.onFinishChange(function(value) { if(value === true) prism.classList.add("solid"); else prism.classList.remove("solid"); }); function goRainbowMode(value) { [].forEach.call(sides, function(elem, i) { if(value === true) sides[i].style.color = "hsl(" + 360 * (i / myOptions.sideCount) + ", 80%, 55%)"; else colorChange(myOptions.color); }); } myRainbow.onFinishChange(goRainbowMode); function checkAnimateThroughSpectrum() { if(myOptions.animateThroughSpectrum) [].forEach.call(sides, function(elem, i) { sides[i].style.color = "hsl(" + c + ", 80%, " + (20 + (i / myOptions.sideCount) * 40) + "%)"; }); else if(myOptions.rainbowMode) goRainbowMode(true); else colorChange(myOptions.color); } // The music player listeners audioInput.addEventListener('change', function(event) { if(event.target.files[0]) { // No error checking of file here, could be added stream = URL.createObjectURL(event.target.files[0]); loadSong(stream); } }, false); if(listenButton) listenButton.addEventListener('click', chooseOneOfMine, false); playPauseButton.addEventListener('click', togglePlayPause, false); // The music functions function setup() { // Stop the previous song if there is one if(audio) togglePlayPause(); audio = new Audio(); audioctx = new AudioContext(); analyser = audioctx.createAnalyser(); analyser.smoothingTimeConstant = 0.75; analyser.fftSize = 512; audio.addEventListener('ended', songEnded, false); sourceNode = audioctx.createMediaElementSource(audio); sourceNode.connect(analyser); sourceNode.connect(audioctx.destination); } function loadSong(stream) { setup(); audio.src = stream; togglePlayPause(); document.body.classList.add('loaded'); update(); } function songEnded() { document.body.classList.remove('loaded'); togglePlayPause(); } function togglePlayPause() { if(paused) { document.body.classList.add('loaded'); audio.play(); playPauseButton.innerText = "▮▮"; } else if(!audio.paused && !audio.ended) { audio.pause(); playPauseButton.innerText = "▶"; } paused = !paused; } function chooseOneOfMine() { var num = Math.round(Math.random() * (myMusic.length - 1)) + 1; loadSong(myMusic[num]); } // The drawing functions function drawSide(freqSequence, freqPercent) { // Get the number of rectangles based on the freqValue drawRectangles(freqSequence, Math.floor(freqPercent * myOptions.rectangleCount / 100)) } function drawRectangles(sideNum, numRectanglesShowing) { for(var i = 0; i < myOptions.rectangleCount; i++) { if(i <= numRectanglesShowing) { rectangleArray[sideNum][i].classList.remove("hide"); } else { rectangleArray[sideNum][i].classList.add("hide"); } } } var sectionsAveraged = [maxSideNum], countSinceLast = [maxSideNum]; function update() { var currTime = Date.now(); var freqArray = new Uint8Array(analyser.frequencyBinCount); analyser.getByteTimeDomainData(freqArray); // Find the average of the values near to each other (grouping) var average = 0, count = 0, numPerSection = 256 / (myOptions.sideCount + 1), nextSection = numPerSection; for (var i = 0; i < freqArray.length; i++) { var v = freqArray[i]; average += Math.abs(128 - v); // 128 is essentially 0 count++; if(i > nextSection) { var currentSection = Math.floor(i / numPerSection - 1); sectionsAveraged[currentSection] += average / count; countSinceLast[currentSection]++; average = 0; count = 0; nextSection += numPerSection; } } // Find the average of the values since the last time checked per section (smoothing) if(currTime - lastTime > timeGap) { for (var i = 0; i < myOptions.sideCount; i++) { drawSide(i, (sectionsAveraged[i] / countSinceLast[i]), c); sectionsAveraged[i] = 0; countSinceLast[i] = 0; } lastTime = currTime; } checkAnimateThroughSpectrum(); c += 0.5; requestAnimationFrame(update); } };
Download Code trình phát nhạc
Để mọi chuyện đơn giản hơn, bạn có thể download toàn bộ code trình phát nhạc này về và sử dụng ngay lập tức trên trình duyệt. Link download ngay bên dưới.
Sau khi tải về, bạn hãy giải nén và mở thư mục dist và chạy file index.html trên trình duyệt là được.
Thế Thôi
Bài viết chia sẻ code trình phát nhạc cho người dùng giúp bạn dễ dàng sử dụng và chỉnh sửa. Bạn có thể copy code để dùng hoặc tải toàn bộ code này để chạy ngay lập tức.
Chúc các bạn vui vẻ và thành công.
Bài viết liên quan: