Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

利用SVG实现表示百分比的圆环 #18

Open
wanCheng7 opened this issue Sep 7, 2019 · 0 comments
Open

利用SVG实现表示百分比的圆环 #18

wanCheng7 opened this issue Sep 7, 2019 · 0 comments

Comments

@wanCheng7
Copy link
Owner

wanCheng7 commented Sep 7, 2019

前言

最近项目中有一个页面需要显示一个带有百分比的圆环,效果如下:
image

我在网上找了些资料后发现很多人都是用SVG实现的

实现步骤

最开始,我其实只找到了这么个demo,它只是实现了圆环的基本效果:
image

可我我要的圆角加渐变怎么办呢?于是又找找找,发现了两个重要属性能实现,圆角是靠stroke-linecap属性设为round就可以了,颜色渐变就负责一些了,直接上代码吧:

<defs>
              <linearGradient id='svg_1' x1='0%' y1='0%' x2='100%' y2='64.9%'>
                <stop offset='0%' stop-color='#f8cb9c' />
                <stop offset='50%' stop-color='#ef9383' />
                <stop offset='100%' stop-color='#ea7575' />
              </linearGradient>
            </defs>
<circle
              cx='90'
              cy='90'
              r='80'
              strokeWidth='12'
              stroke='url(#svg_1)'
              fill='none'
              stroke-linecap='round'
              transform='matrix(0,-1,1,0,0,180)'
              strokeDasharray={this.getRingPercent(resultObj.score, 80)}
            ></circle>

感觉有点像css的·keyframes`有木有,通过设置几个节点的颜色值从而达到一个渐变的效果。

最后总体说一些实现思路,实际上就是通过两个circle标签,一个现实的是底色的环,一个是变化的环,而这个根据数值变化的环主要是靠stroke-dasharray属性实现的:

stroke-dasharray 的两个值,一个表示虚线的长度,另一个表示虚线与虚线之间的间距,而间距之间是一片空白,所以图形从圆变成了圆弧。然而这好像和我们想象中的有点不一样,我们希望它是从右上方开始的。所以我们需要转换一下坐标系。

所以stroke-dasharray第一个值就是你要展示的圆弧长度,而第二个值就是圆弧的周长,这个都是可以换算出来的。

用react实现的完整代码如下:

<svg width='180' height='180' viewBox='0 0 180 180'>
            <defs>
              <linearGradient id='svg_1' x1='0%' y1='0%' x2='100%' y2='64.9%'>
                <stop offset='0%' stop-color='#f8cb9c' />
                <stop offset='50%' stop-color='#ef9383' />
                <stop offset='100%' stop-color='#ea7575' />
              </linearGradient>
            </defs>
            <circle
              cx='90'
              cy='90'
              r='80'
              strokeWidth='12'
              stroke='#3e2eae'
              fill='none'
            ></circle>
            <circle
              cx='90'
              cy='90'
              r='80'
              strokeWidth='12'
              stroke='url(#svg_1)'
              fill='none'
              stroke-linecap='round'
              transform='matrix(0,-1,1,0,0,180)'
              strokeDasharray={this.getRingPercent(resultObj.score, 80)}
            ></circle>
          </svg>

// 计算圆环长度数据
  getRingPercent = (percent, r) => {
    let perimeter = Math.PI * 2 * r; //周长
    return (percent / 100) * perimeter + ' ' + perimeter;
  };

目前实现的最终效果如下:
image

总结

其实这只是用SVG实现的一个很小的例子,后来无意中翻看像F2这种图形库时发现已经有现成的实现了,该是怪自己孤陋寡闻啊,哈哈,所以我相当于造了一个简单的轮子吧,毕竟我这个项目也只需要这个一个小图形,就引以整个库对性能也不好,他们那些库也无非是用SVG或者convas实现的,嗯,也只能这样安慰自己了,哈哈。

还是希望有机会多用用SVG和canvas吧,觉得这种矢量绘图还蛮有意思的,目前对SVG的api了解还不是很多,相当于照葫芦画瓢,用的多了对一些核心API理解多了应该会更得心应手一些!

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant