UNPKG

music-visualization-canvas

Version:
208 lines (205 loc) 7.86 kB
import { __assign } from 'tslib'; var MusicVisualization = /** @class */ (function () { function MusicVisualization(options) { var _this = this; this.options = __assign({ gap: 0, minHeight: 10, el: document.body, audioEvents: {} }, options); var el = this.options.el; this.drawRafId = null; this.objectUrl = ''; this.canvas = this.createCanvas(); this.canvasCtx = this.canvas.getContext('2d'); this.options.el.appendChild(this.canvas); this.canvas.width = el.clientWidth; this.canvas.height = el.clientHeight; this.analyser = null; this.audio = this.createAudio(); Object.keys(this.options.audioEvents).forEach(function (key) { _this.audio.addEventListener(key, _this.options.audioEvents[key]); }); this.resizeObserver = new ResizeObserver(function (entries) { for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { var entry = entries_1[_i]; _this.canvas.width = entry.target.clientWidth; _this.canvas.height = entry.target.clientHeight; } }); this.resizeObserver.observe(el); } MusicVisualization.prototype.start = function () { var _this = this; if (!this.audio.src) { return; } // playing if (!this.audio.paused && this.audio.duration > 0) { return; } this.createAnalyser(); return this.audio.play().then(function () { _this.draw(); }); }; MusicVisualization.prototype.stop = function () { if (this.drawRafId) { window.cancelAnimationFrame(this.drawRafId); this.drawRafId = null; } return this.audio.pause(); }; MusicVisualization.prototype.destroy = function () { var _this = this; this.stop(); if (this.objectUrl) { window.URL.revokeObjectURL(this.objectUrl); } Object.keys(this.options.audioEvents).forEach(function (key) { _this.audio.removeEventListener(key, _this.options.audioEvents[key]); }); this.resizeObserver.unobserve(this.options.el); this.analyser = null; }; MusicVisualization.prototype.changeMusic = function (file) { if (this.objectUrl) { window.URL.revokeObjectURL(this.objectUrl); } this.objectUrl = window.URL.createObjectURL(file); this.stop(); this.audio.src = this.objectUrl; this.start(); }; /** * 创建canvas */ MusicVisualization.prototype.createCanvas = function () { var canvas = document.createElement('canvas'); canvas.style.cssText = 'position: absolute; left: 0; bottom: 0; width: 100%; height: 100%; pointer-events: none;'; return canvas; }; /** * 创建audio */ MusicVisualization.prototype.createAudio = function () { var audio = new Audio(); audio.src = this.options.src; audio.preload = 'auto'; audio.volume = 0.8; audio.loop = true; audio.crossOrigin = 'anonymous'; return audio; }; /** * 创建auido 分析器 * @param audio */ MusicVisualization.prototype.createAnalyser = function () { if (this.analyser) { return; } var audioCtx = new (AudioContext || webkitAudioContext)(); var source = audioCtx.createMediaElementSource(this.audio); var analyser = audioCtx.createAnalyser(); source.connect(analyser); analyser.connect(audioCtx.destination); analyser.fftSize = 256; this.analyser = analyser; }; /** * 画曲线 * @param param0 */ MusicVisualization.prototype.drawCurveLine = function (_a) { var startX = _a.startX, startY = _a.startY, stopX = _a.stopX, stopY = _a.stopY, scaleY = _a.scaleY, arr = _a.arr; var height = this.canvas.height; var canvasCtx = this.canvasCtx; var minHeight = this.options.minHeight; var len = arr.length; var sliceWidth = stopX / (len - 1); var lastX = startX; var lastY = startY; for (var index = 0; index < len - 1; index++) { var x = lastX + sliceWidth; var y = ((height / 3) * (arr[index] / 256) + minHeight) * scaleY; // 取当前点 和 上一个点的中点, 模拟曲线 var middleX = (lastX + x) / 2; var middleY = (lastY + y) / 2; canvasCtx.quadraticCurveTo(lastX, lastY, middleX, middleY); lastX = x; lastY = y; } canvasCtx.quadraticCurveTo(lastX, lastY, stopX, stopY * scaleY); }; MusicVisualization.prototype.drawGraph = function (arr) { var canvasCtx = this.canvasCtx; var _a = this.options, minHeight = _a.minHeight, gap = _a.gap; var singleWidth = this.canvas.width / 2 - gap; canvasCtx.beginPath(); canvasCtx.moveTo(0, 0); canvasCtx.lineTo(0, minHeight); this.drawCurveLine({ startX: 0, startY: minHeight, stopX: singleWidth, stopY: minHeight, scaleY: 1, arr: arr }); canvasCtx.lineTo(singleWidth, 0); canvasCtx.fill(); }; MusicVisualization.prototype.drawLine = function (arr) { var canvasCtx = this.canvasCtx; var _a = this.options, gap = _a.gap, minHeight = _a.minHeight; var singleWidth = this.canvas.width / 2 - gap; canvasCtx.beginPath(); canvasCtx.moveTo(0, 0); this.drawCurveLine({ startX: 0, startY: minHeight, stopX: singleWidth, stopY: minHeight, scaleY: 1.1, arr: arr }); canvasCtx.stroke(); }; MusicVisualization.prototype.draw = function () { if (!this.analyser) { return; } var _a = this.canvas, width = _a.width, height = _a.height; var gap = this.options.gap; var _b = this, analyser = _b.analyser, canvasCtx = _b.canvasCtx; var singleWidth = width / 2 - gap; var bufferLength = analyser.frequencyBinCount - 5; var dataArray = new Uint8Array(bufferLength).slice(0, -20); analyser.getByteFrequencyData(dataArray); canvasCtx.clearRect(0, 0, width, height); var gradientLeft = canvasCtx.createLinearGradient(0, 0, singleWidth, 0); gradientLeft.addColorStop(0, '#ff30a2'); gradientLeft.addColorStop(1, '#d8db31'); var gradientRight = canvasCtx.createLinearGradient(0, 0, singleWidth, 0); gradientRight.addColorStop(0, '#00cf2e'); gradientRight.addColorStop(1, '#3bddd2'); // 镜像 翻转 左边 canvasCtx.save(); canvasCtx.transform(1, 0, 0, -1, 0, height); canvasCtx.fillStyle = gradientLeft; canvasCtx.strokeStyle = gradientLeft; this.drawGraph(dataArray); this.drawLine(dataArray); canvasCtx.restore(); // 镜像再 翻转 右边 canvasCtx.save(); canvasCtx.transform(-1, 0, 0, -1, width, height); canvasCtx.fillStyle = gradientRight; canvasCtx.strokeStyle = gradientRight; this.drawGraph(dataArray); this.drawLine(dataArray); canvasCtx.restore(); this.drawRafId = requestAnimationFrame(this.draw.bind(this)); }; return MusicVisualization; }()); export default MusicVisualization; //# sourceMappingURL=index.es.js.map