公司最近新项目有一个展现数据操作进度的需求,由于公司内使用的UI库只有线性进度条而没有环形进度条,所以只得手写一个封装组件,尝试了多种方案后比较一下优劣。
1.利用普通HTML+CSS绘制
这种方案的原理是两个半圆进行旋转和覆盖,当进度不大于50%时,左侧半圆进行顺时针旋转;大于50%时,右侧半圆顺时针旋转,只需控制旋转的角度与进度相关即可。
具体可参照【css】手把手教你实现 css 环形进度条 - 知乎 (zhihu.com);
缺陷:由于进度条分为两部分,两个部分之间会出现一条不很明显的缝,影响美观,故没有采纳。
2.利用canvas
对于canvas来说,使用arc()方法画一个圆环是非常方便的,也是我一开始采用的方案。原理即利用arc方法和save方法绘制两个重合的圆环。
代码:
import './index.scss';
import * as React from 'react';
interface IRingProgressOwnProps {
progress: number;
size: number;
tracksColor?: string | undefined;
thumbColor?: string | undefined;
lineWidth?: number | undefined;
children?: React.ReactNode;
}
export const RingProgress = (props: IRingProgressOwnProps) => {
let canvas: null | HTMLCanvasElement;
const canvasEl = React.useRef(null);
React.useEffect(() => {
canvas = canvasEl.current;
const ctx = canvas!.getContext('2d');
ctx!.clearRect(0, 0, canvas!.offsetWidth, canvas!.offsetWidth);
drawTracksRing(ctx);
drawThumbRing(ctx, props.progress);
}, []);
const drawTracksRing = (ctx: CanvasRenderingContext2D | null): void => {
ctx?.save();
ctx?.beginPath();
ctx!.strokeStyle &#