项目中需要一个圆形进度条,本着能省则省的原则,先去elementui上看了下,傻眼了,不一样,ui直接否定了这个办法。这个是设计,这个是elementui上面的,差很多吗?yes!
去百度了发现自己画一个也不是很费事,经过一番思想建设,对,就是在想ui为啥要求这么严格,哈哈哈,开干!
先画了个差不多的,两个圆圈简单点,代码如下:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<circle cx="60" cy="60" r="40" fill="RGB(222,212,238)" />
<circle cx="60" cy="60" r="32" stroke="#F5003C"
stroke-width="8" fill="RGB(222,212,238)"/>
</svg>
这个没啥难点,cx,cy,r分别表示圆心(x,y)和半径r,stroke-width是圆的边,stroke表示边的颜色,fill表示整个圆的填充颜色。其实就是两个同心圆,里面的圆的边带有一定的宽度,展现出来效果就是上面这样了。
下面开始难点的,就是进度不是100%时,只是一段圆弧的情况。
怕说不明白,画了个图示一下。
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<circle cx="40" cy="40" r="40" fill="RGB(222,212,238)" />
<path d="M 40 8 A 32 32, 0, 0, 1, 40,72" stroke="#F5003C" stroke-width="8" fill="RGB(222,212,238)" />
</svg>
上面的path就是画弧线的指令,d="M 40 8 A 32 32, 0, 0, 1, 40,72",d="M 起点x 起点y A 圆心x 圆心y, 0, 0(画小弧), 1,终点x, 终点y“。加上文字,text标签,之前不知道,以为只能有一个text,后来发现可以有无数个,前提是装得下,字体的样式,就是css中,font的各个属性直接添加在标签上。
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<circle cx="40" cy="40" r="40" fill="RGB(222,212,238)" />
<path d="M 40 8 A 32 32, 0, 0, 1, 40,72" stroke="#F5003C" stroke-width="8" fill="RGB(222,212,238)" />
<text x="25" y="48" fill="green" font-size="20" font-style="italic">55</text>
<text x="50" y="48" fill="green" font-size="13" font-style="italic">%</text>
</svg>
下面附上我用vue写的一个组件,里面外层圆大小只计算了80,60两种,项目中是够用了。
<template>
<div class="contain-c-progress">
<svg :id="cid" :width="cwidth" :height="cwidth" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle :cx="cr.cx" :cy="cr.cy" :r="bgr" :fill="bg" />
<path v-if="percent!=100" :d="cd" :stroke="strokeColor" :stroke-width="strokeWidth" :fill="bg" />
<circle v-if="percent==100" :cx="cr.cx" :cy="cr.cy" :r="r" :stroke="strokeColor" :stroke-width="strokeWidth" :fill="bg" />
<text :x="textPos.x" :y="textPos.y" :fill="strokeColor" :font-size="fontSize.f0" font-style="italic">{{percent}}</text>
<text :x="textPos.x1" :y="textPos.y1" :fill="strokeColor" :font-size="fontSize.f1" font-style="italic">%</text>
</svg>
</div>
</template>
<script type="text/ecmascript-6">
export default {
name: "Cprogress",
data() {
return {};
},
props: {
cw: {
required: true,
type: Number
},
id: {
required: true,
type: Number
},
bg: {
required: true,
type: String
},
strokeColor: {
type: String,
required: true
},
strokeWidth: {
type: Number,
required: true
},
percent: {
type: Number,
required: true
}
},
computed: {
//整个svg的大小
cwidth() {
return this.cw + "px";
},
//path的起点
start() {
if (this.cw == 80) {
return { sx: 40, sy: 8 };
} else {
return { sx: 30, sy: 6 };
}
},
//背景圆的半径
bgr() {
return this.cw / 2;
},
//弧线半径
r() {
return this.cw==80? this.cw / 2 - 8 : this.cw/2 -6;
},
//弧线的圆心
cr() {
return { cx: this.cw / 2, cy: this.cw / 2 };
},
//path 终点
end() {
//终点位置
var alpha = this.percent / 100 * 2 * Math.PI;
var ex = this.cw / 2 + this.r * Math.sin(alpha);
var ey = this.cw / 2 - this.r * Math.cos(alpha);
return { x: ex, y: ey };
},
cd() {
//示例:"M50 10 A 40 40, 0, 0, 1, 50 90"
return this.percent <= 50
? `M ${this.start.sx} ${this.start.sy}
A ${this.r} ${this.r}, 0, 0, 1,${this.end.x} ${this.end.y}`
: `M ${this.start.sx} ${this.start.sy}
A ${this.r} ${this.r}, 0, 1, 1,${this.end.x} ${this.end.y}`;
},
cid() {
//svg的id
return "svg" + this.id;
},
textPos() {
//文字x方向位置
if (this.cw == 80) {
if (this.percent < 10) {
return { x: 30, y: 48, x1: 43, y1: 48};
} else if (this.percent < 100) {
return { x: 22, y: 48, x1: 47, y1: 48};
} else {
return { x: 14, y: 48, x1: 51, y1: 48 };
}
} else {
if (this.percent < 10) {
return { x: 22, y: 37, x1: 33, y1: 37 };
} else if (this.percent < 100) {
return { x: 12, y: 37, x1: 33, y1: 37 };
} else {
return { x: 8, y: 37, x1: 38, y1: 37 };
}
}
},
//文字大小
fontSize(){
if(this.cw==80){
return {f0: 20, f1: 13}
}else if(this.cw==60){
return {f0: 16, f1: 12}
}
}
}
};
</script>
<style scoped>
svg {
text-align: center;
line-height: 100px;
color: #fff;
}
</style>
<cprogress :cw="80" :id="index" :stroke-width='8' stroke-color="#F62256" bg="#FFDDDD"
:percent="100"></cprogress>
最终显示效果:
溜了溜了,设计要来找我了