首先创建一个.jsx文件
输入rfc,创建组件模板
import React from 'react'
export default function index() {
return (
<div>
</div>
)
}
再把canvas元素引入,顺便把组件模板稍微改下
import React from 'react'
const index = props => {
return (
<canvas ></canvas>
)
}
export default index
接着设置canvas的id,因为这个组件可能重复使用,所以我们要保证每次创建的时候生成不同的id
import React, { useState, useEffect } from 'react'
const index = props => {
const [ids, setId] = useState()
useEffect(() => {
let id = ('_' + Math.random()).replace('.', '_');
setId(id)
}, [])
return (
<canvas id={ids}></canvas>
)
}
export default index
再然后是关键的一步,绘制圆环,使用这个函数,具体见canvas api
const drawCircle = (_options) => {
var options = _options || {}; //获取或定义options对象;
options.angle = options.angle || [0.3, 0.3, 0.2, 0.2]; //定义默认角度1为360度(角度范围 0-1);
options.color = options.color || '#111'; //定义默认颜色(包括字体和边框颜色);
options.lineWidth = options.lineWidth || 10; //定义默认圆描边的宽度;
options.num = options.num || 0
var oBoxOne = document.getElementById(options.id);
oBoxOne.width = oBoxOne.width //重置宽刷新canvas
var sCenter = oBoxOne.width / 2; //获取canvas元素的中心点;
var ctx = oBoxOne.getContext('2d');
var nBegin = Math.PI / 2; //定义起始角度;
var nEnd = Math.PI * 2; //定义结束角度;
ctx.textAlign = 'center'; //定义字体居中;
ctx.font = 'normal normal bold 24px Arial'; //定义字体加粗大小字体样式;
ctx.fillStyle = '#202224'; //判断文字填充样式为颜色,还是渐变色;
ctx.fillText((options.angle[options.num] * 100).toFixed(1) + '%', sCenter, sCenter); //设置填充文字;
ctx.lineCap = options.lineCap;
ctx.lineWidth = options.lineWidth;
ctx.beginPath(); //设置起始路径,这段绘制360度背景;
ctx.strokeStyle = '#D8D8D8';
ctx.arc(sCenter, sCenter, (sCenter - options.lineWidth), -nBegin, nEnd, false);
ctx.stroke();
var nBegins = []
var nEnds = []
let sum = 0
options.angle.forEach(item => {
nBegins.push(sum * nEnd)
sum += item
nEnds.push(sum * nEnd)
})
const draw = (nBegin, nEnd, color) => { //该函数实现角度绘制;
var imd = ctx.getImageData(0, 0, 240, 240);
ctx.putImageData(imd, 0, 0);
ctx.beginPath();
ctx.strokeStyle = color ? color : '#6699FF';
ctx.arc(sCenter, sCenter, (sCenter - options.lineWidth), nBegin, nEnd, false);
ctx.stroke();
}
for (var i = 0; i < nBegins.length; i++) {
draw(nBegins[i], nEnds[i], colors[i])
}
}
接着把这个函数在组件中使用,angle的数组表示把圆环分成4段,num表示环中间显示数字是数组的第一位,显示的样式是百分百。
import React, { useState, useEffect } from 'react'
const index = props => {
const [ids, setId] = useState()
useEffect(() => {
let id = ('_' + Math.random()).replace('.', '_');
setId(id)
}, [])
useEffect(() => {
if (ids) {
drawCircle({ id: ids, angle: [0.2,0.3,0.4,0.1] ,num={1})
}
}, [ids])
const drawCircle = (_options) => {
...
}
return (
<canvas id={ids}></canvas>
)
}
export default index
这个angle和num可以改成外部传入,外部还需要传入高度和宽度。
import React, { useState, useEffect } from 'react'
const index = props => {
const { width, height, angle, num } = props
const [ids, setId] = useState()
useEffect(() => {
let id = ('_' + Math.random()).replace('.', '_');
setId(id)
}, [])
useEffect(() => {
if (ids) {
drawCircle({ id: ids, angle: angle, num: num })
}
}, [ids])
const drawCircle = (_options) => {
...
}
return (
<canvas id={ids} width={width ? width : 150} height={height ? height : 150}></canvas>
)
}
export default index
这样一个圆环就完成了