关于javascript:svg实现reactrax圆环倒计时进度条组件code-snippet

成果:

不必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>
  );
};

备注:

  1. 呈现stroke width不失效:rax中疑似不能把stroke-width写成strokeWidth。
  2. 圆环半径不影响理论尺寸,但留神依据本人的圆环半径调整viewbox尺寸防止显示不残缺,本例圆环半径32.。
  3. 圆环起起点坐标雷同,故应用path形式绘制时,必须要设定一个门路的两头点,本例设定了180度地位为两头点。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理