效果图:

 

1、需求:

接口返回一个数组,每一项均是一个数字,代表着y坐标,x坐标需自己处理。

我的数据是1024个浮点数,在-10到10之间

波形图需要xy轴缩放功能,用c3的 transform: scale()是不行的,至少会失真。

然后背景的格子,我这里是每个格子要求100个点,初始缩放下是11个格子,10条线(竖线)

2、绘制所需的方法

1、创建canvas实例。

按uni-app文档所说,小程序的canvas需要一个唯一的canvas-id属性(属性名不同平台可能有差异,参照官网)以区分页面中不同的canvas。this则是vue实例。

let content = uni.createCanvasContext('waveform', this);

2、绘制格子

首先,调用uni.getSystemInfo获取屏幕宽度,这样就能根据不同屏幕来计算图形的xy坐标,做到每个屏幕的显示比例的都一样。换成父容器宽度也可,看你需求。

//横线
for (let i = -80; i <= 80; i += 20) {
       content.moveTo(0, i);
       content.lineTo(1100, i)
     }
// 竖线
// 计算两条线之间的距离。windowWidth:屏幕宽度
let widthInterval = Number(this.windowWidth) / 11;
// x坐标缩放比例
let scalc = 100 / widthInterval;
for (let j = 1; j <= 10; j++) {
         content.moveTo(j * widthInterval, -100);
         content.lineTo(j * widthInterval, 100)
     }

moveTo是将画笔移动到哪里。canvas画图就像我们画画,落笔之前首先要将笔尖移动到目标点。

lineTo传入一个坐标,然后将该坐标与上一次收笔的坐标连接起来,形成一条线。

示意图:

 注意:moveTo仅移动画笔,不会绘制。lineTo才会绘制。

完成以上,仅仅是创建路径,相当于蓝图。下面将蓝图实现。

content.setStrokeStyle("#797979");
content.translate(0, 100);
content.stroke();
content.beginPath();
content.moveTo(0, 0)

第一个应该不用多说,设置线条颜色。

第二个,因为canvas坐标轴原点默认在左上角顶点,绘制过程中所有坐标点都是相对于该原点的,如果坐标有负数,则会超出canvas,像使用position超出盒子一样。所以使用该方法移动原点,我这里将y坐标向下移了100像素。

第三个,将当前描绘好的路径画成真的线条。实现蓝图的方法

第四个,至此,格子已经 画好了,由于格子跟图形是分开的,不能互相影响。调用此方法可以新建一个路径(canvas一开始就默认帮我们调用了一次)。

第五个,将画笔重新移动至原点。

3、绘制折线图

                this.wave?.map((item, index) => {
                    content.lineTo(
                        (index / scalc),
                        (item * this.multipleList[this.currentMultiple] * 0.02)) 
                })

                content.setStrokeStyle("limegreen");
                // content.translate(0, 100);
                content.stroke();
                content.draw(false)

wave是数据源

是这样的:因为我需求是每个格子100个点,1024个点共11个格子,如果一个数据点占据一个像素,那么就需要1024个像素,但移动端显然不可能这么大。于是,获取到屏幕宽度后,计算出比例,就可以得出每个坐标点占据的像素。

至于multipleList,则是缩放功能使用到的倍数列表。可自行决定。

最后一个方法:draw : 将上面所有东西绘制至canvas。通常在末尾调用。

3、结尾

整体难度不大,但如果不了解canvas绘图原理,还是很麻烦的,如果看不懂文章,建议先去官网看看,有更好的讲述。

还有一个小地方:坐标点有无限小数也无所谓,canvas会自动处理,些许差别肉眼看不出来。

最后,这是我加班没事干写着玩的,也是第一次写博客,写的不好请见谅。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐