React下用SVG實現(xiàn)一個半圓形儀表盤

2017-07-21 10:51:12來源:威易網(wǎng)作者:joe

用SVG實現(xiàn)一個半圓形儀表盤

由于需要在網(wǎng)頁中展示一個如下的效果:

\
儀表盤

項目開發(fā)采用的是React,使用 Ant Design 組件庫,我發(fā)現(xiàn)Ant Design中有一個Progress很像。

Process使用的是rc_progress,實現(xiàn)過程很巧妙,首先通過兩個圓,然后將要顯示進度的圓變成虛線,通過調(diào)節(jié)虛線起始位置來實現(xiàn)進度的變化。我也類似的做了一個儀表盤,對Process做了一些調(diào)整。

具體步驟如下:

首先畫兩個圓,一個為底圖,一個為進度圖。畫法是分別左右畫一個半圓。

const pathString = `M 50,50 m 0,${radius}
  a ${radius},${radius} 0 1 1 0,-${2 * radius}
  a ${radius},${radius} 0 1 1 0,${2 * radius}`;

然后將底圖的圓變成虛線,虛線中不顯示的部分我開口的部分

const len = Math.PI * 2 * radius;
const trailPathStyle = {
  strokeDasharray: `${len - openWidth}px ${len}px`,
  strokeDashoffset: `${openWidth / 2}px`,
  transition: 'stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease',
};

同樣的方法,將進度圓也修改為虛線

const strokePathStyle = {
  strokeDasharray: `${percent / 100 * (len - openWidth)}px ${len}px`,
  strokeDashoffset: `${openWidth / 2}px`,
  transition: 'stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease',
};

SVG部分代碼如下:

      <svg
        className={`${prefixCls}-circle ${className}`}
        viewBox="0 0 100 100"
        style={style}
        {...restProps}
      >
        <path
          className={`${prefixCls}-circle-trail`}
          d={pathString}
          stroke={trailColor}
          strokeWidth={trailWidth || strokeWidth}
          fillOpacity="0"
        />
        <path
          className={`${prefixCls}-circle-path`}
          d={pathString}
          strokeLinecap={strokeLinecap}
          stroke={strokeColor}
          strokeWidth={strokeWidth}
          fillOpacity="0"
          ref={(path) => { this.path = path; }}
          style={pathStyle}
        />
      </svg>

這部分代碼我已經(jīng)提交了一個建議給Ant Design,希望他們能做的更好。

后記,相關(guān)的SVG知識

<path> 標簽:用來定義路徑。

下面的命令可用于路徑數(shù)據(jù):

M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
C = curveto
S = smooth curveto
Q = quadratic Belzier curve
T = smooth quadratic Belzier curveto
A = elliptical Arc
Z = closepath

注釋:以上所有命令均允許小寫字母。大寫表示絕對定位,小寫表示相對定位。

stroke-dasharray 是用于設(shè)置虛線的屬性。你可以使用它來設(shè)置每條劃線長度以及劃線之間空格的大小著作權(quán)歸作者所有。

<svg width="600px" height="300px">
    <line x1="0" y1="20" x2="600" y2="20" stroke="#000" stroke-width="3" stroke-dasharray="10 2"/>
    <line x1="0" y1="40" x2="600" y2="40" stroke="#000" stroke-width="3" stroke-dasharray="5 10"/>
    <line x1="0" y1="60" x2="600" y2="60" stroke="#000" stroke-width="3" stroke-dasharray="1 1"/>
    <line x1="0" y1="80" x2="600" y2="80" stroke="#000" stroke-width="3" stroke-dasharray="10"/>
</svg>

第一個值是劃線的長度,第二個值是各個劃線之間的空格大小。如果你只設(shè)置了一個值(如上面的最后一個示例),它會默認設(shè)置相同劃線長度和劃線空格。

stroke-dashoffset屬性是設(shè)置虛線的偏移量。

<svg width="600px">
    <line x1="0" y1="20" x2="600" y2="20" stroke="#000" stroke-width="3"
          stroke-dasharray="50 30"/>
    <line x1="0" y1="40" x2="600" y2="40" stroke="#000" stroke-width="3"
          stroke-dasharray="50 30"
          stroke-dashoffset="10"/>
</svg>

第二條線設(shè)置stroke-dashoffset=10,線條偏移了10。

關(guān)鍵詞:SVGReact