CircleRing.tsx 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import { View } from "@tarojs/components";
  2. import { useEffect } from "react";
  3. let SvgXml;
  4. if (process.env.TARO_ENV == 'rn') {
  5. SvgXml = require("react-native-svg").SvgXml
  6. }
  7. export default function CircleRing(props: {
  8. size: number,
  9. thickness: number,
  10. startAngle: number,
  11. progress: number,
  12. color: string,
  13. backgroundColor?: string
  14. }) {
  15. const center = props.size / 2;
  16. const radius = (props.size - props.thickness) / 2;
  17. function detail() {
  18. const strokeWidth = props.thickness
  19. // 计算圆周长
  20. const circumference = 2 * Math.PI * radius;
  21. const startAngle = props.startAngle
  22. const progress = props.progress
  23. // 计算起始点的坐标
  24. const startX = props.size / 2 + radius * Math.cos((startAngle - 90) * (Math.PI / 180));
  25. const startY = props.size / 2 + radius * Math.sin((startAngle - 90) * (Math.PI / 180));
  26. // 计算结束点的坐标
  27. const endAngle = startAngle + (progress / 100) * 360;
  28. const endX = props.size / 2 + radius * Math.cos((endAngle - 90) * (Math.PI / 180));
  29. const endY = props.size / 2 + radius * Math.sin((endAngle - 90) * (Math.PI / 180));
  30. return `<svg width="${props.size}" height="${props.size}" xmlns="http://www.w3.org/2000/svg">
  31. <circle cx="${props.size / 2}" cy="${props.size / 2}" r="${radius}" stroke="${props.backgroundColor ?? 'transparent'}" stroke-width="${strokeWidth}" fill="none" />
  32. <path d="M ${startX} ${startY} A ${radius} ${radius} 0 ${progress > 50 ? 1 : 0} 1 ${endX} ${endY}"
  33. stroke="${props.color}" stroke-width="${strokeWidth}" fill="none" stroke-linecap="round" />
  34. </svg>`
  35. }
  36. useEffect(() => {
  37. }, [])
  38. return <View style={{ width: props.size, height: props.size }}>{
  39. process.env.TARO_ENV == 'weapp' ? <mysvg src={detail()} colors={[]} /> :
  40. <SvgXml xml={detail()} />
  41. }</View>
  42. }