今天跟大家分享一下最近根據業務需求開發的一個動態百分比餅圖的react元件(今天比較閒)
我先是用CSS3做發現做不到這種效果,然後嘗試用Canvas,做到一半發現也不合適而且有模糊的問題遂放棄。最後決定用SVG!
主要思路就是用path橢圓弧指令(A)畫扇形,然後根據增量(輸入框內的值)來增加或減小扇形的弧度,輸入框只是用來演示的,實際上要用到後臺介面資料
HTML結構如下:
SVG橢圓弧路徑指令說明:(來自CSDN)
指令 | A (絕對) a (相對) |
---|---|
名稱 | elliptical arc 橢圓弧 |
引數 | 程式碼:A rx ry x-axis-rotation large-arc-flag sweep-flag x y rx ry 是橢圓的兩個半軸的長度。 x-axis-rotation 是橢圓相對於座標系的旋轉角度,角度數而非弧度數。 large-arc-flag 是標記繪製大弧(1)還是小弧(0)部分。 sweep-flag 是標記向順時針(1)還是逆時針(0)方向繪製。 x y 是圓弧終點的座標。 |
描述 | 從當前點繪製一段橢圓弧到點 (x, y),橢圓的大小和方向由 (rx, ry) 和 x-axis-rotation 引數決定, x-axis-rotation 參數列示橢圓整體相對於當前座標系統的旋轉角度。橢圓的中心座標 (cx, cy) 會自動進行計算從而滿足其它引數約束。large-arc-flag 和 sweep-flag 也被用於圓弧的計算與繪製。 |
先不考慮動畫效果,只看怎麼畫一個扇形:(說起來比較麻煩,就在註釋上逐行說吧)
其中PI為我在元件前面定義的常量:const PI = 3.1416
上面程式碼宣告的x1,y1,x2,y2代表的是起點和終點弧邊的座標,如圖所示:
這樣繪製扇形的function就寫好了~
接下來就是要讓它動起來!還要如絲般順滑!咋整呢?當然用requestAnimationFrame了!如果你還不瞭解它請移步->MDN傳送門
接下來就去呼叫animationSvg就好了,可以從輸入框取到弧度值,或者從後臺的資料中獲取計算,注意一定要從百分比轉化成弧度:
const value = Number((this.input.value / 100) * PI * 2);
this.animationSvg(value);複製程式碼
這樣就實現了文章開頭GIF的那種效果,總結起來就是:
- 獲取到資料,增量或者減量,單位為弧度;
- 執行requestAnimationFrame動畫;
- 計算path並渲染在DOM中;
- 重複執行2~3兩步直到到達弧度的終點
眼見為實,大家可以去這裡看到線上DEMO:傳送門
可能程式碼的實現方式還不是最簡潔的,各路大神路過歡迎給出建議~