效果圖:
?
1、需求:
接口返回一個(gè)數(shù)組,每一項(xiàng)均是一個(gè)數(shù)字,代表著y坐標(biāo),x坐標(biāo)需自己處理。
我的數(shù)據(jù)是1024個(gè)浮點(diǎn)數(shù),在-10到10之間
波形圖需要xy軸縮放功能,用c3的 transform: scale()是不行的,至少會(huì)失真。
然后背景的格子,我這里是每個(gè)格子要求100個(gè)點(diǎn),初始縮放下是11個(gè)格子,10條線(豎線)
2、繪制所需的方法
1、創(chuàng)建canvas實(shí)例。
按uni-app文檔所說(shuō),小程序的canvas需要一個(gè)唯一的canvas-id屬性(屬性名不同平臺(tái)可能有差異,參照官網(wǎng))以區(qū)分頁(yè)面中不同的canvas。this則是vue實(shí)例。
let content = uni.createCanvasContext('waveform', this);
2、繪制格子
首先,調(diào)用uni.getSystemInfo獲取屏幕寬度,這樣就能根據(jù)不同屏幕來(lái)計(jì)算圖形的xy坐標(biāo),做到每個(gè)屏幕的顯示比例的都一樣。換成父容器寬度也可,看你需求。
//橫線
for (let i = -80; i <= 80; i += 20) {
content.moveTo(0, i);
content.lineTo(1100, i)
}
// 豎線
// 計(jì)算兩條線之間的距離。windowWidth:屏幕寬度
let widthInterval = Number(this.windowWidth) / 11;
// x坐標(biāo)縮放比例
let scalc = 100 / widthInterval;
for (let j = 1; j <= 10; j++) {
content.moveTo(j * widthInterval, -100);
content.lineTo(j * widthInterval, 100)
}
moveTo是將畫(huà)筆移動(dòng)到哪里。canvas畫(huà)圖就像我們畫(huà)畫(huà),落筆之前首先要將筆尖移動(dòng)到目標(biāo)點(diǎn)。
lineTo傳入一個(gè)坐標(biāo),然后將該坐標(biāo)與上一次收筆的坐標(biāo)連接起來(lái),形成一條線。
示意圖:
?注意:moveTo僅移動(dòng)畫(huà)筆,不會(huì)繪制。lineTo才會(huì)繪制。
完成以上,僅僅是創(chuàng)建路徑,相當(dāng)于藍(lán)圖。下面將藍(lán)圖實(shí)現(xiàn)。
content.setStrokeStyle("#797979");
content.translate(0, 100);
content.stroke();
content.beginPath();
content.moveTo(0, 0)
第一個(gè)應(yīng)該不用多說(shuō),設(shè)置線條顏色。
第二個(gè),因?yàn)閏anvas坐標(biāo)軸原點(diǎn)默認(rèn)在左上角頂點(diǎn),繪制過(guò)程中所有坐標(biāo)點(diǎn)都是相對(duì)于該原點(diǎn)的,如果坐標(biāo)有負(fù)數(shù),則會(huì)超出canvas,像使用position超出盒子一樣。所以使用該方法移動(dòng)原點(diǎn),我這里將y坐標(biāo)向下移了100像素。
第三個(gè),將當(dāng)前描繪好的路徑畫(huà)成真的線條。實(shí)現(xiàn)藍(lán)圖的方法
第四個(gè),至此,格子已經(jīng) 畫(huà)好了,由于格子跟圖形是分開(kāi)的,不能互相影響。調(diào)用此方法可以新建一個(gè)路徑(canvas一開(kāi)始就默認(rèn)幫我們調(diào)用了一次)。
第五個(gè),將畫(huà)筆重新移動(dòng)至原點(diǎn)。
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是數(shù)據(jù)源
是這樣的:因?yàn)槲倚枨笫敲總€(gè)格子100個(gè)點(diǎn),1024個(gè)點(diǎn)共11個(gè)格子,如果一個(gè)數(shù)據(jù)點(diǎn)占據(jù)一個(gè)像素,那么就需要1024個(gè)像素,但移動(dòng)端顯然不可能這么大。于是,獲取到屏幕寬度后,計(jì)算出比例,就可以得出每個(gè)坐標(biāo)點(diǎn)占據(jù)的像素。
至于multipleList,則是縮放功能使用到的倍數(shù)列表??勺孕袥Q定。
最后一個(gè)方法:draw : 將上面所有東西繪制至canvas。通常在末尾調(diào)用。
3、結(jié)尾
整體難度不大,但如果不了解canvas繪圖原理,還是很麻煩的,如果看不懂文章,建議先去官網(wǎng)看看,有更好的講述。
還有一個(gè)小地方:坐標(biāo)點(diǎn)有無(wú)限小數(shù)也無(wú)所謂,canvas會(huì)自動(dòng)處理,些許差別肉眼看不出來(lái)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-858256.html
最后,這是我加班沒(méi)事干寫(xiě)著玩的,也是第一次寫(xiě)博客,寫(xiě)的不好請(qǐng)見(jiàn)諒。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-858256.html
到了這里,關(guān)于uni-app+vue2 微信小程序 使用canvas繪制折線圖/波形圖的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!