Html5 Canvas繪製大型波形數據

數據採用Float32Array保存。html

http://www.ieyebrain.com:8080/upload/scroll.htmlhtml5

1 分頁機制canvas

用一個Pager的類來操做。函數

function Pager(buf, pageSize) {
        this.buf = buf;
        this.pageSize = pageSize;
        this.viewStart = -1;
        this.getView = function(pos) {
            if (this.viewStart >= 0 && pos >= this.viewStart && pos < this.viewStart + this.pageSize) {
                console.log('cache hit');
                return true;
            } else {
                var view = this.buf.subarray(pos, pos + this.pageSize);
                this.viewStart = pos;
                console.log('cache miss, get view again length is ' + view.length);
                return view;
            }
        };
    }this

getView函數能夠返回任何位置一個頁面數據。內部維護一個cache,當移動不大的時候就不會切換View。firefox

2 頁面元素orm

html5種。用兩個div元素,第一個爲真實圖形,第二個只是爲了提供大範圍的滾動條。
<div id="divWave" style="overflow-x:hidden">
    <canvas  id='waveform' height="100" width="32766" ></canvas>
</div>

<div id="divWaveOut" style="overflow-x:auto">
    <canvas  id='waveform-out' height="1" width="3276600" ></canvas>
</div>htm

3 將大範圍的滾動條scroll事件轉化爲對視圖的局部滾動或者換頁操做。事件

waveOut.addEventListener('scroll', function(e) {
            e.preventDefault();
            var pos = this.scrollLeft;
            onGobalSeek(pos);
            return false;
        }, true
);get

4 視圖更新函數

function onGobalSeek(newPos) {
        var oldPos = pager.viewStart;
        var view = pager.getView(newPos);
        if ('boolean' == typeof view) { //頁面內局部滾動
            var leftOld = waveObj.container.scrollLeft;
            var leftNew = newPos - oldPos;
            waveObj.container.scrollLeft = leftNew;
            console.log('just scroll it from ' + leftOld + ' -> ' + leftNew);
        } else { //換頁
            waveObj.drawShape(view);
            waveObj.container.scrollLeft  = 0;
            console.log('redraw it');
        }
    }

5  繪圖

function drawShape(buf){
                var ctx = this.ctx;
                this.waveform.width = this.waveform.width;

                //此爲重要細節。firefox中,若是用clearRect不會馬上更新畫面。
                ctx.beginPath();
                var y = ~~(buf[0]);
                ctx.moveTo(0, y);
                for (var i = 1; i < buf.length; i++) {
                    y = ~~(buf[i]);
                    ctx.lineTo(i, y);
                }
                ctx.stroke();
                ctx.closePath();
            }

另外:

http://www.ieyebrain.com:8080/audio/wavesurfer.js/

對wavesurfer.js的使用,和增長編輯功能。

相關文章
相關標籤/搜索