Html5 Canvas绘制大型波形数据

数据采用Float32Array保存。

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

1 分页机制

用一个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;
            }
        };
    }

getView函数可以返回任何位置一个页面数据。内部维护一个cache,当移动不大的时候就不会切换View。

2 页面元素

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>

3 将大范围的滚动条scroll事件转化为对视图的局部滚动或者换页操作。

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

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/upload/scroll.html

你可能感兴趣的:(canvas,html5,waveform)