最近要在小程序里实现波形图的效果,我就使用了
setInterval和ctx.draw(),但是我发现,如果setinterval的频率过高,或者画布上画的东西过多,系统的内存就会飙升,帧率也会大幅度下降,然而我之前用js在html上这样画是没有问题的,作为一名菜鸟,真心的请教下是不是我哪里代码写的不对,具体代码如下
wxml
< view class = 'canvaDiv' > < canvas class = 'canvas' canvas-id = "canvas" ></ canvas > </ view > < button bindtap = 'start' >开始测试</ button > |
wxss
.canvaDiv { margin-bottom : 5 rpx; } .canvas { width : 100% ; height : 400px ; border : 1 rpx solid #dadada ; border-bottom : 1 rpx; } |
js
start: function (e) { console.log( "start" ); var that = this ; var size = wx.getSystemInfoSync().windowWidth; //屏幕宽度,波形图的宽度 var space = size / 1024; //x坐标每次移动的长度 var offset = 4; //每次跨越的数据长度,offset越小interval越小,画面就越流畅,性能消耗就越高 var interval = 1000 / 128 * offset; //隔几毫秒画一次 var obj = { buffer: new Array(), index: 0 } for ( var i = 0; i < 2048; i++) { obj.buffer.push(Math.random() * 128); } let ctx = wx.createCanvasContext( "canvas" ); setInterval( function () { that.drawWave(space, offset, obj, ctx, 0); that.drawWave(space, offset, obj, ctx, 128); that.drawWave(space, offset, obj, ctx, 256); ctx.stroke(); ctx.draw(); if (obj.buffer.length >= 1024) { //如果铺满画布了,就移动 obj.index += offset; //计时器每执行一次,索引就偏移一定量 } if (obj.buffer.length <= obj.index) { obj.index = 0; } }, interval); }, drawWave: function (space, offset, obj, ctx, heightOffset) { var x = 0; //x开始的位置 if (obj.buffer.length > obj.index) { ctx.moveTo(x, obj.buffer[obj.index]); //线的起点 for ( var i = 0; i < 1024; i++) { //1屏8秒128*8=1024个数据 if (obj.buffer.length > obj.index + i) { ctx.lineTo(x += space, obj.buffer[obj.index + i] + heightOffset); } } } } |
是我哪里写的不对吗,求指点
楼主,你好,我也是在用小程序绘制实时波形,画到后面也会卡顿,请用你解决了你的问题吗?
操作 dom 的动画,20fps 对小程序来说就算极限了。
单单你 for 个 1 千次 setData 都能看到卡,这和 H5 是没法比的。
视觉端与 js 端沟通成本极大,不推荐这样玩。
太频繁了,手机的处理能力不如电脑,而且这还是小程序。
嗯,如果只有一条波的话会好很多,帧率也基本能保持在60,但是不知道为什么内存却整体上一直在增长,就好像是用来内存就不释放了一样,不知道是不是哪内存泄漏了,我js并不熟悉,网上查了下说有可能是闭包导致的,但是我理解的不是太明白,研究了半天还是每发现哪有问题,你能帮我在看一下吗
你试试每次画图的时候先清理下呢 clearRect
试了一下,貌似还是不行
比如每秒系统能处理10条绘画,但是你每秒放了20条进去,那么积累起来的事件会变多,会是这个原因吗?你把频率降到很低了观察下呢
频率降低就会好很多,当我设置成1秒重绘一次的时候,基本内存和帧率就很稳定了,但是我们这边要求这个波形要平滑的移动,这就至少要100毫秒重绘一次了。。。然而我试过100毫秒,根本不行,我再想想其他办法吧,谢谢你了