效果:
不用svg几乎都是需要有额外的元素遮挡实现,但没有办法做到半透明圆环效果。纯svg画,加宽path的stroke宽度视觉上呈现圆环。(是不是高中学过的三角函数快忘光了?)
以半径32的圆环为例,注意画笔定位基准落在中心位置,需要调整viewbox尺寸避免出现圆环显示不完整。(拷贝自用)
import { createElement, useState, useEffect, useRef, useCallback } from 'rax';
interface IProps {
time: number; // milliseconds
style?: Rax.CSSProperties;
onEnd?: () => void;
}
export const CircleTimer = (props: IProps) => {
const curT = useRef(0);
const timer = useRef<number>();
const [point, setPoint] = useState('32 0');
useEffect(() => {
return () => {
if (timer.current) {
clearTimeout(timer.current);
}
};
}, []);
const calPoint = useCallback(() => {
if (curT.current >= props.time) {
props.onEnd && props.onEnd();
return;
}
timer.current = setTimeout(() => {
curT.current += 50;
const deg = (curT.current / props.time) * Math.PI * 2;
const x = 32 + 32 * Math.sin(deg);
const y = 32 - 32 * Math.cos(deg);
if (curT.current < (1 / 2) * props.time) {
setPoint(`${x} ${y}`);
} else if (curT.current > (1 / 2) * props.time) {
setPoint(`32 64 A 32 32 0 0 1 ${x} ${y}`);
}
calPoint();
}, 50);
}, [props.time, props.onEnd]);
useEffect(() => {
calPoint();
}, [calPoint]);
return (
<svg
width="60rpx"
height="60rpx"
style={props.style || {}}
viewBox="-2 -2 68 68"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<path
d={`M32 0 A 32 32 0 0 1 ${point}`}
stroke="white"
fill="transparent"
stroke-width="4"
/>
</svg>
);
};
备注:
- 出现stroke width不生效:rax中疑似不能把stroke-width写成strokeWidth。
- 圆环半径不影响实际尺寸,但注意根据自己的圆环半径调整viewbox尺寸避免显示不完整,本例圆环半径32.。
- 圆环起终点坐标相同,故使用path方式绘制时,必须要设定一个路径的中间点,本例设定了180度位置为中间点。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。