本次分享一下在canvas中將繪製出來的折線段的稜角「磨平」,也就是通過貝塞爾曲線穿過各個描點來代替原有的折線圖。
歡迎關注我的部落格,不定期更新中——
先來看下echarts下折線圖的渲染效果:
一開始我沒注意到其實這個折線段是曲線穿過去的,只認為是單純的描點繪圖,所以起初我實現的「簡(醜)易(陋)」版本是這樣的:
不要關注樣式,重點就是實現之後才發現看起來人家echarts的實現描點非常的圓滑,也由此引發了之後的**。怎麼有規律的畫平滑曲線?
先來看下最終模仿的實現:
因為我也不知道echarts內部怎麼實現的(逃
看起來已經非常圓潤了,和我們最初的設想十分接近了。再看下曲線是否穿過了描點:
好的!結果很明顯現在來重新看下我們的實現方式。
模擬資料
var data = [math.random() * 300];
for (var i = 1; i < 50; i++)
option = ,
series: ,
areastyle: ,
data: data}};
繪製折線圖
首先初始化乙個建構函式來放置需要用到的資料:
function
lineargradient
(option)
繪製折線圖:
上面的公式涉及到四個座標點,當前點,前乙個點以及後兩個點,而當座標值為下圖展示的時候繪製出來的曲線如下所示:
所以在將折線換成平滑曲線的時候,將邊界值以及其他控制點計算好之後代入到貝塞爾函式中就完成了:
//核心實現
this.series.data.foreach(function
(item, index) else
if(index ===1) else
if(index === self.series.data.length - 1)
self.ctx.beziercurveto(cax, cay, cbx, cby, nowx, nowy);
//繪製出上乙個點到當前點的貝塞爾曲線
})
由於我每次遍歷的點都是當前點,但是文章中給出的公式是計算會知道下乙個點的控制點演算法,故在**實現中我將所有點的計算挪前了一位。當index = 0時也就是初始點是不需要曲線繪製的,因為我們繪製的是從前乙個點到當前點的曲線,沒有到0的曲線需要繪製。從index = 1開始我們就可以正常開始繪製,從0到1的曲線,由於index = 1時是沒有在他前面第二個點的故其屬於邊界值點,也就是需要特殊進行計算,以及最後乙個點。其餘均按照正常公式算出ab的xy座標代入貝塞爾函式即可。
源**見這裡
慣例po作者的部落格,不定時更新中——
有問題歡迎在issues下交流。
使用canvas繪製貝塞爾曲線
1 二次貝塞爾曲線 quadraticcurveto cpx,cpy,x,y cpx,cpy表示控制點的座標,x,y表示終點座標 數學公式表示如下 二次方貝茲曲線的路徑由給定點p0 p1 p2的函式b t 追蹤 例項 複製 如下 canvas直線 效果 2 三次貝塞爾曲線 beziercurveto...
canvas效果案例 貝塞爾曲線
繪製二次貝塞爾曲線 ctx.quadraticcurveto x1,y1,x,y 從上一點開始繪製一條二次曲線,到 x,y 為止,並且以 x1,y1 作為控制點 ctx.beginpath ctx.strokestyle green ctx.linewidth 4 起始點 ctx.moveto 10...
貝塞爾曲線使用
貝塞爾曲線數學公式 1。兩個控制點 線性公式 x 1 t x0 t x1 0 t 1 y 1 t y0 t y1 0 t 1 2.三個控制點 二次公式 x 1 t 1 t x0 2 t 1 t x1 t t x2 0 t 1 y 1 t 1 t y0 2 t 1 t y1 t t y2 0 t 1 ...