首頁  >  文章  >  web前端  >  H5的Canvas如何實現繪製音樂環形頻譜圖

H5的Canvas如何實現繪製音樂環形頻譜圖

php中世界最好的语言
php中世界最好的语言原創
2018-03-12 15:11:474704瀏覽

這次帶給大家H5的Canvas如何實現繪製音樂環形頻譜圖,H5Canvas實現繪製音樂環形頻譜圖的注意事項有哪些,下面就是實戰案例,一起來看一下。

在B站我們有很多的小伙伴們應該都看到過用AE做的可視化音樂播放器播放音樂的視頻,看著特別酷炫帶感有木有。

H5的Canvas如何實現繪製音樂環形頻譜圖

所以今天我就用 Canvas 來做個簡單 環形頻譜圖。

那麼~ ヾ(o・ω・)ノ 開始吧!

1.首先繪製靜態的效果

靜態效果

#繪製靜態效果很簡單,我們只要從一點出發根據一定角度繪製線條,接著畫個圓從中點開始覆蓋線條就行了

<canvas id="wrap" height="800" width="800"></canvas><script>
    var wrap = document.getElementById("wrap");    var cxt = wrap.getContext("2d");
    (function drawSpectrum() {
        cxt.clearRect(0, 0, wrap.width, wrap.height);        //画线条
        for (var i = 0; i < 360; i++) {            var value = 8;
            cxt.beginPath();
            cxt.lineWidth = 2;
            cxt.moveTo(300, 300);             //R * cos (PI/180*一次旋转的角度数) ,-R * sin (PI/180*一次旋转的角度数)
            cxt.lineTo(Math.cos((i * 1) / 180 * Math.PI) * (200 + value) + 300, (- Math.sin((i * 1) / 180 * Math.PI) * (200 + value) + 300));
            cxt.stroke();
        }        //画一个小圆,将线条覆盖
        cxt.beginPath();
        cxt.lineWidth = 1;
        cxt.arc(300, 300, 200, 0, 2 * Math.PI, false); 
        cxt.fillStyle = "#fff";
        cxt.stroke();
        cxt.fill(); 
    })();</script>

2.呼叫AudioAPI,繪製音樂的頻譜圖

繪製音樂的頻譜圖

第一步完成後,第二步就很簡單了,透過呼叫AudioAPI取得音訊變化來改變線條長度。

注意! ! !最新chrome瀏覽器可能需要在http伺服器上執行~

你可以參考文章繪製音樂的頻譜圖(使用Analyser節點)

<input type="button" onclick="audio.play()" value="播放" /><input type="button" onclick="audio.pause()" value="暂停" /><canvas id="wrap" height="800" width="800"></canvas><script> 
    var wrap = document.getElementById("wrap");    var cxt = wrap.getContext("2d");    //获取API
    var AudioContext = AudioContext || webkitAudioContext;    var context = new AudioContext;    //加载媒体
    var audio = new Audio("demo.mp3");    //创建节点
    var source = context.createMediaElementSource(audio);    var analyser = context.createAnalyser();    //连接:source → analyser → destination
    source.connect(analyser);
    analyser.connect(context.destination);    //创建数据
    var output = new Uint8Array(360);
    (function drawSpectrum() {
        analyser.getByteFrequencyData(output);//获取频域数据
        cxt.clearRect(0, 0, wrap.width, wrap.height);        //画线条
        for (var i = 0; i < 360; i++) {            var value = output[i] / 8;//<===获取数据
            cxt.beginPath();
            cxt.lineWidth = 2;
            cxt.moveTo(300, 300);            //R * cos (PI/180*一次旋转的角度数) ,-R * sin (PI/180*一次旋转的角度数)
            cxt.lineTo(Math.cos((i * 1) / 180 * Math.PI) * (200 + value) + 300, (- Math.sin((i * 1) / 180 * Math.PI) * (200 + value) + 300));
            cxt.stroke();
        }        //画一个小圆,将线条覆盖
        cxt.beginPath();
        cxt.lineWidth = 1;
        cxt.arc(300, 300, 200, 0, 2 * Math.PI, false);
        cxt.fillStyle = "#fff";
        cxt.stroke();
        cxt.fill();        //请求下一帧
        requestAnimationFrame(drawSpectrum);
    })();</script>

3.環形左右同步顯示

#實習步驟2後其實已經完成一大半了,不過細心的小伙伴們會發現環形最右端點上的線條間差了很多。

處理辦法很多,我們用其中一個簡單的辦法處理,那就是讓其左右對稱的顯示。

<input type="button" onclick="audio.play()" value="播放" /><input type="button" onclick="audio.pause()" value="暂停" /><canvas id="wrap" height="550" width="800"></canvas><script> 
    var wrap = document.getElementById("wrap");    var cxt = wrap.getContext("2d");    //获取API
    var AudioContext = AudioContext || webkitAudioContext;    var context = new AudioContext;    //加载媒体
    var audio = new Audio("demo.mp3");    //创建节点
    var source = context.createMediaElementSource(audio);    var analyser = context.createAnalyser();    //连接:source → analyser → destination
    source.connect(analyser);
    analyser.connect(context.destination);    //创建数据
    var output = new Uint8Array(361);
    (function drawSpectrum() {
        analyser.getByteFrequencyData(output);//获取频域数据
        cxt.clearRect(0, 0, wrap.width, wrap.height);        //画线条
        for (var i = 0; i < output.length; i++) {            var value = output[i] / 10;            //绘制左半边
            cxt.beginPath();
            cxt.lineWidth = 1;
            cxt.moveTo(300, 300);
            cxt.lineTo(Math.cos((i *0.5 + 90) / 180 * Math.PI) * (200 + value) + 300, (- Math.sin((i *0.5 + 90) / 180 * Math.PI) * (200 + value) + 300));
            cxt.stroke();            //绘制右半边
            cxt.beginPath();
            cxt.lineWidth = 1;
            cxt.moveTo(300, 300);
            cxt.lineTo( (Math.sin((i *0.5) / 180 * Math.PI) * (200 + value) + 300),-Math.cos((i *0.5) / 180 * Math.PI) * (200 + value) + 300);
            cxt.stroke();
        }        //画一个小圆,将线条覆盖
        cxt.beginPath();
        cxt.lineWidth = 1;
        cxt.arc(300, 300, 200, 0, 2 * Math.PI, false);
        cxt.fillStyle = "#fff";
        cxt.stroke();
        cxt.fill();        //请求下一帧
        requestAnimationFrame(drawSpectrum);
    })();</script>

4.新增波形圖

最後我們來嘗試在圈內,新增一個波形圖

你可以參考文章繪製音樂的波形圖(使用Analyser節點)

範例

<input type="button" onclick="audio.play()" value="播放" /><input type="button" onclick="audio.pause()" value="暂停" /><canvas id="wrap" height="550" width="800"></canvas><script> 
    var wrap = document.getElementById("wrap");    var cxt = wrap.getContext("2d");    //获取API
    var AudioContext = AudioContext || webkitAudioContext;    var context = new AudioContext;    //加载媒体
    var audio = new Audio("demo.mp3");    //创建节点
    var source = context.createMediaElementSource(audio);    var analyser = context.createAnalyser();    //连接:source → analyser → destination
    source.connect(analyser);
    analyser.connect(context.destination);    //创建数据
    var output = new Uint8Array(361);    //计算出采样频率44100所需的缓冲区长度
    var length = analyser.frequencyBinCount * 44100 / context.sampleRate | 0;    //创建数据 
    var output2 = new Uint8Array(length);
    (function drawSpectrum() {
        analyser.getByteFrequencyData(output);//获取频域数据
        cxt.clearRect(0, 0, wrap.width, wrap.height);        //画线条
        for (var i = 0; i < output.length; i++) {            var value = output[i] / 10;            //绘制左半边
            cxt.beginPath();
            cxt.lineWidth = 1;
            cxt.moveTo(300, 300);
            cxt.lineTo(Math.cos((i * 0.5 + 90) / 180 * Math.PI) * (200 + value) + 300, (- Math.sin((i * 0.5 + 90) / 180 * Math.PI) * (200 + value) + 300));
            cxt.stroke();            //绘制右半边
            cxt.beginPath();
            cxt.lineWidth = 1;
            cxt.moveTo(300, 300);
            cxt.lineTo((Math.sin((i * 0.5) / 180 * Math.PI) * (200 + value) + 300), -Math.cos((i * 0.5) / 180 * Math.PI) * (200 + value) + 300);
            cxt.stroke();
        }        //画一个小圆,将线条覆盖
        cxt.beginPath();
        cxt.lineWidth = 1;
        cxt.arc(300, 300, 200, 0, 2 * Math.PI, false);
        cxt.fillStyle = "#fff";
        cxt.stroke();
        cxt.fill();        //将缓冲区的数据绘制到Canvas上 
        analyser.getByteTimeDomainData(output2);        var height = 100, width = 400;
        cxt.beginPath();        for (var i = 0; i < width; i++) {
            cxt.lineTo(i + 100, 300 - (height / 2 * (output2[output2.length * i / width | 0] / 256 - 0.5)));
        }
        cxt.stroke();        //请求下一帧
        requestAnimationFrame(drawSpectrum);
    })();</script>

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

相關閱讀:

如何使用canvas來製作好用的塗鴉畫板

如何使用s-xlsx實作Excel文件導入和導出(下)

#

以上是H5的Canvas如何實現繪製音樂環形頻譜圖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn