扇形圖
用svg的path標(biāo)簽可以畫出任何你想畫的圖像
這里有一篇詳細(xì)的指南,有興趣的可以看下:svg的path
這里再引用一位博主寫的不錯(cuò)的文章:SVG之path
path標(biāo)簽的d屬性的命令有
- M = moveto
- L = lineto
- H = horizontal lineto
- V = vertical lineto
- C = curveto
- S = smooth curveto
- Q = quadratic Bézier curve
- T = smooth quadratic Bézier curveto
- A = elliptical Arc
- Z = closepath
我們這里只要用到M L A 和Z命令就可以了,M L 和Z命令比較簡(jiǎn)單,這里詳細(xì)講解A命令,A命令是畫弧的命令拄踪,里面的A命令有 7個(gè)參數(shù):rx ry x-axis-rotation large-arc-flag sweep-flag x y
rx ry 表示橢圓的x半徑和y半徑,兩個(gè)一樣畫出來的就是圓,最后兩個(gè)的參數(shù)x y表示的是終點(diǎn)坐標(biāo)脑融,接下來的三個(gè)參數(shù)比較復(fù)雜,這里開始詳細(xì)講解:
我們來看一張圖:articlex.png
圖中的兩個(gè)點(diǎn)Arc start 和Arc end是起始點(diǎn)和終止點(diǎn)缩宜,假設(shè)我們已經(jīng)知道肘迎,通過這兩個(gè)點(diǎn)和半徑可以得出兩個(gè)橢圓,四條弧锻煌,那該怎樣確定用那條弧呢妓布?在起始點(diǎn)和終止點(diǎn)之間連一條線,在線的左半部分sweep-flag的值為0宋梧,在右邊為1匣沼,而當(dāng)large-arc-flag為1時(shí)表示取的是大弧,為0就表示取小弧捂龄,這兩個(gè)參數(shù)的四種取值就可以分別取出這四條弧释涛。large-arc-flag(約定名稱叫大弧,下文也這么叫)=0就表示取圖中B和C的兩條加黑的小弧倦沧,而sweep-flag(約定名稱叫鏡像唇撬,下文也這么叫)=0表示取B中的那條小弧,等于1表示取圖C中的那條展融,(大弧窖认,鏡像)的四種取值:(0,0)告希、(0扑浸,1)、(1燕偶,0)喝噪、(1,1)就分別對(duì)應(yīng)圖中的B指么、C酝惧、D驰吓、E。x-axis-rotation表示的就是x軸的旋轉(zhuǎn)角度系奉,如圖F
好檬贰,A命令的參數(shù)講完之后我們開始講用path標(biāo)簽畫扇形的原理:
再來看張圖:
扇形圖原理
扇形圖是圓的一部分,要畫出圖中的扇形圖分三步:
#1:從圓心(400缺亮,300)畫一條直線到弧的起點(diǎn)位置
#2:從弧的起點(diǎn)位置畫一條弧到終點(diǎn)位置
#3:閉合路徑
第一條線比較好畫M L命令可以實(shí)現(xiàn)翁涤,但是我們首先要求出起點(diǎn)的坐標(biāo)x,y萌踱。畫第二條弧的時(shí)候還要求出終點(diǎn)坐標(biāo)葵礼,最后第三條線用Z命令直接閉合就可以了。
所以這里我們要寫一個(gè)求坐標(biāo)的函數(shù)并鸵,還要注意所有的度數(shù)都得轉(zhuǎn)成弧度制鸳粉,再寫一個(gè)轉(zhuǎn)弧度制的函數(shù),怎么求弧的起點(diǎn)左邊x园担、y届谈?x坐標(biāo)就是圓心的cx坐標(biāo)+圖示的線段a,而線段a=r*sin(ang)弯汰,r表示半徑艰山,ang表示角度,角度是我們自己給的咏闪,終點(diǎn)坐標(biāo)同理曙搬。
這里寫的時(shí)候用一個(gè)數(shù)組存d屬性的命令,最后用空格拼接在統(tǒng)一設(shè)置鸽嫂。
注意:
在畫扇形圖的時(shí)候纵装,當(dāng)終點(diǎn)和起點(diǎn)之間的角度小于180°的時(shí)候,large-arc-flag取0据某,大于180°的時(shí)候取1橡娄,所以我們可以用三元運(yùn)算符實(shí)現(xiàn) ‘?:’哗脖;
還有就是Arc start和Arc end兩個(gè)點(diǎn)如果重合瀑踢,svg將畫不出任何曲線扳还。因?yàn)榻?jīng)過一個(gè)點(diǎn)的弧有無數(shù)條
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#oSvg{
background: rgba(187, 187, 187, 0.2);
}
</style>
<script>
window.onload=function(){
let oP1=document.getElementById('p1');//獲取path對(duì)象
let cx=300,cy=300,r=200;//圓心坐標(biāo)才避、半徑
let ang1=120,ang2=420;//角度
function d2a(n){//角度轉(zhuǎn)弧度
return n*Math.PI/180;
}
function pointe(ang){//求坐標(biāo)函數(shù)
return {
x:cx+r*Math.sin(d2a(ang)),
y:cy-r*Math.cos(d2a(ang))
}
}
let arr=[];//存d屬性的參數(shù)
//#1
let {x:x1,y:y1}=pointe(ang1);//求出弧的起點(diǎn)坐標(biāo),線的終止點(diǎn)氨距,命名x1桑逝,y1
arr.push(`M ${cx} ${cy} L ${x1} ${y1}`);//畫出從圓心到弧的線,但是這里還沒畫俏让,只是添加到數(shù)組里了楞遏,最后的時(shí)候在一起畫
//#2
let {x:x2,y:y2}=pointe(ang2);//求出弧的終止點(diǎn)茬暇,命名x2,y2
arr.push(`A ${r} ${r} 0 ${ang2-ang1>=180?1:0} 1 ${x2} ${y2}`);//畫出第二條弧寡喝,這里也還沒開始畫糙俗,只是加到數(shù)組里了
//#3
arr.push('Z')//閉合
oP1.setAttribute('d',arr.join(' '));//拼接數(shù)組里的字符,開始畫
}
</script>
</head>
<body>
<svg width='800' height='600' id="oSvg">
<path id="p1" style="stroke: rgb(255, 136, 0); stroke-width:5;fill:none"></path>
</svg>
</body>
</html>