Rings.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { Canvas } from "@tarojs/components";
  2. import Taro from "@tarojs/taro";
  3. import { useDidShow, useReady } from "@tarojs/taro";
  4. import { useEffect, useRef } from "react";
  5. export type RingCommon = {
  6. useCase: string;
  7. status: string;
  8. isFast?: boolean;
  9. radius: number;
  10. lineWidth: number;
  11. }
  12. export type CurrentDot = {
  13. color: string;
  14. lineWidth: number;
  15. borderColor: string;
  16. }
  17. export type RealRing = {
  18. color: string;
  19. startArc: number;
  20. durationArc: number;
  21. }
  22. export type TargetRing = {
  23. color: string;
  24. startArc: number;
  25. durationArc: number;
  26. }
  27. export type BgRing = {
  28. color: string;
  29. }
  30. export default function Rings(props: {
  31. common: RingCommon; currentDot?: CurrentDot;
  32. realRing?: RealRing; targetRing?: TargetRing; bgRing: BgRing; canvasId?: string;
  33. }) {
  34. const progress = 0.85
  35. const r = props.common.radius
  36. const strokeWidth = props.common.lineWidth;
  37. // const color = props.color || 'orange'
  38. const canvasRef = useRef(null);
  39. const canvasId = props.canvasId ? 'canvas_' + props.canvasId : 'progress-canvas';
  40. const dpr = Taro.getSystemInfoSync().pixelRatio; // 获取设备的像素比
  41. const radius = r; // 圆形进度条的半径
  42. const lineWidth = strokeWidth; // 圆形进度条的线宽
  43. useDidShow(() => {
  44. // drawCircle()
  45. })
  46. useReady(() => {
  47. drawCircle()
  48. })
  49. function drawCircle() {
  50. const query = Taro.createSelectorQuery();
  51. query.select(`.${canvasId}`).fields({ node: true, size: true });
  52. query.exec((res) => {
  53. if (res[0] == null) return;
  54. const _canvas = res[0].node;
  55. _canvas.width = res[0].width * dpr;
  56. _canvas.height = res[0].height * dpr;
  57. const ctx = _canvas.getContext('2d');
  58. // const ctx = Taro.createCanvasContext(canvasId);
  59. const center = radius + lineWidth / 2; // 圆心坐标
  60. ctx.clearRect(0, 0, radius * 2, radius * 2); // 清除画布
  61. // 设置画布尺寸
  62. ctx.scale(dpr, dpr);
  63. // 绘制背景圆
  64. ctx.beginPath();
  65. ctx.arc(center, center, radius, 0, 2 * Math.PI);
  66. ctx.lineWidth = lineWidth;
  67. ctx.strokeStyle = props.bgRing.color;
  68. ctx.lineCap = 'round'; // 设置为圆角
  69. ctx.stroke();
  70. // 绘制target进度圆
  71. if (props.common.useCase == 'ChooseScenario') {
  72. ctx.beginPath();
  73. ctx.arc(center, center, radius, props.targetRing!.startArc,
  74. props.targetRing!.startArc + props.targetRing!.durationArc);
  75. ctx.lineWidth = lineWidth;
  76. ctx.strokeStyle = props.targetRing!.color;
  77. ctx.lineCap = 'round'; // 设置为圆角
  78. ctx.stroke();
  79. }
  80. //绘制current_dot点
  81. if (props.common.useCase == 'Clock'){
  82. var time = new Date();
  83. var seconds = time.getHours()*3600+time.getMinutes()*60+time.getSeconds();
  84. var arc = seconds/86400*2*Math.PI-Math.PI/2.0;
  85. ctx.beginPath();
  86. ctx.arc(center, center, radius, arc,
  87. arc+0.001);
  88. ctx.lineWidth = lineWidth;
  89. ctx.strokeStyle = props.currentDot!.borderColor;
  90. ctx.lineCap = 'round'; // 设置为圆角
  91. ctx.stroke();
  92. ctx.beginPath();
  93. ctx.arc(center, center, radius, arc,
  94. arc+0.001);
  95. ctx.lineWidth = lineWidth-2;
  96. ctx.strokeStyle = props.currentDot!.color;
  97. ctx.lineCap = 'round'; // 设置为圆角
  98. ctx.stroke();
  99. }
  100. // ctx.draw();
  101. });
  102. }
  103. useEffect(() => {
  104. drawCircle()
  105. }, [props.targetRing,props.currentDot]);
  106. return <Canvas canvasId={canvasId} id={canvasId} className={canvasId} type="2d" style={{ width: (radius * 2 + lineWidth), height: (radius * 2 + lineWidth), zIndex: 0 }} ref={canvasRef} />
  107. }