Html5 Canvas绘制大型波形数据

本文介绍了一种基于HTML5的音视频数据分页显示方案,利用Pager类管理数据缓存,通过绘制波形图展示音频文件内容,并实现了大范围滚动条到局部视图滚动的转化。

数据采用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/audio/wavesurfer.js/

对wavesurfer.js的使用,和增加编辑功能。

 

转载于:https://my.oschina.net/u/612750/blog/529443

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值