Rings.rn.tsx 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import { TimeFormatter } from "@/utils/time_format";
  2. import { View } from "@tarojs/components";
  3. import Taro from "@tarojs/taro";
  4. import { useRef } from "react";
  5. import Svg, { Circle, Path } from 'react-native-svg';
  6. import { useSelector } from "react-redux";
  7. export type RingCommon = {
  8. useCase: string;
  9. status: string;
  10. isFast?: boolean;
  11. radius: number;
  12. lineWidth: number;
  13. }
  14. export type CurrentDot = {
  15. color: string;
  16. lineWidth: number;
  17. borderColor: string;
  18. timestamp?: number;
  19. }
  20. export type RealRing = {
  21. color: string;
  22. startArc: number;
  23. durationArc: number;
  24. }
  25. export type TargetRing = {
  26. color: string;
  27. startArc: number;
  28. durationArc: number;
  29. }
  30. export type BgRing = {
  31. color: string;
  32. }
  33. export default function Component(props: {
  34. common: RingCommon; currentDot?: CurrentDot;
  35. realRing?: RealRing; targetRing?: TargetRing;
  36. breathAnimation?: boolean;
  37. bgRing: BgRing; canvasId?: string;
  38. ctx?: any; setCtx?: any;
  39. canvas?: any; setCanvas?: any;
  40. dotList?: Array<CurrentDot>;
  41. stageList?: Array<RealRing>;
  42. }) {
  43. const r = props.common.radius
  44. const strokeWidth = props.common.lineWidth;
  45. // const color = props.color || 'orange'
  46. const canvasRef = useRef(null);
  47. const canvasId = props.canvasId ? 'canvas_' + props.canvasId : 'progress-canvas';
  48. const dpr = Taro.getSystemInfoSync().pixelRatio; // 获取设备的像素比
  49. const radius = r; // 圆形进度条的半径
  50. const lineWidth = strokeWidth; // 圆形进度条的线宽
  51. const timeObj = useSelector((state: any) => state.time);
  52. const user = useSelector((state: any) => state.user);
  53. const center = radius + lineWidth / 2 + 3; // 圆心坐标
  54. function drawContent() {
  55. var time = new Date();
  56. // if (timeObj.status != 'WAIT_FOR_START' && timeObj && (timeObj.fast || timeObj.sleep)) {
  57. // var timestamp = time.getTime()
  58. // //判断逻辑
  59. // if (timeObj.fast.real_start_time_zone || timeObj.sleep.real_start_time_zone) {
  60. // timestamp = TimeFormatter.transferTimestamp(timestamp, timeObj.fast.real_start_time_zone ? timeObj.fast.real_start_time_zone : timeObj.sleep.real_start_time_zone)
  61. // time = new Date(timestamp)
  62. // }
  63. // }
  64. var seconds = time.getHours() * 3600 + time.getMinutes() * 60 + time.getSeconds();
  65. var arc = seconds / 86400 * 2 * Math.PI - Math.PI / 2.0;
  66. return <Svg width={(radius * 2 + lineWidth) + 6} height={(radius * 2 + lineWidth) + 6} fillOpacity={0}>
  67. <Circle
  68. cx={center}
  69. cy={center}
  70. r={radius}
  71. fillOpacity={0}
  72. stroke={props.bgRing.color}
  73. strokeWidth={strokeWidth}
  74. strokeLinecap="round"
  75. />
  76. {/* // 绘制target进度环
  77. if (props.targetRing) {
  78. ctx.beginPath();
  79. ctx.arc(center, center, radius, props.targetRing!.startArc,
  80. props.targetRing!.startArc + props.targetRing!.durationArc);
  81. ctx.lineWidth = lineWidth;
  82. ctx.strokeStyle = props.targetRing!.color;
  83. ctx.lineCap = 'round'; // 设置为圆角
  84. ctx.stroke();
  85. } */}
  86. {
  87. props.targetRing && <Circle
  88. cx={center}
  89. cy={center}
  90. r={radius}
  91. fillOpacity={0}
  92. stroke={props.targetRing!.color}
  93. transform={`rotate(${props.targetRing!.startArc / (2 * Math.PI) * 360} ${center} ${center})`}
  94. strokeDasharray={`${props.targetRing!.durationArc * radius},1000`}
  95. strokeWidth={lineWidth}
  96. strokeLinecap="round"
  97. />
  98. }
  99. {/* //绘制real进度环
  100. if (props.realRing) {
  101. if (props.realRing.durationArc <0.01) props.realRing.durationArc=0.01;
  102. ctx.beginPath();
  103. ctx.arc(center, center, radius, props.realRing!.startArc,
  104. props.realRing!.startArc + props.realRing!.durationArc);
  105. ctx.lineWidth = lineWidth;
  106. ctx.strokeStyle = props.realRing!.color;
  107. ctx.lineCap = 'round'; // 设置为圆角
  108. ctx.stroke();
  109. } */}
  110. {
  111. props.realRing && <Circle
  112. cx={center}
  113. cy={center}
  114. r={radius}
  115. fillOpacity={0}
  116. stroke={props.realRing!.color}
  117. transform={`rotate(${props.realRing!.startArc / (2 * Math.PI) * 360} ${center} ${center})`}
  118. strokeDasharray={`${props.realRing!.durationArc * radius},1000`}
  119. strokeWidth={lineWidth}
  120. strokeLinecap="round"
  121. />
  122. }
  123. {
  124. props.stageList && props.stageList.map((item) => {
  125. return <Circle
  126. cx={center}
  127. cy={center}
  128. r={radius}
  129. fillOpacity={0}
  130. stroke={item.color}
  131. transform={`rotate(${item.startArc / (2 * Math.PI) * 360} ${center} ${center})`}
  132. strokeDasharray={`${item.durationArc * radius},1000`}
  133. strokeWidth={lineWidth}
  134. strokeLinecap="round"
  135. />
  136. })
  137. }
  138. {
  139. props.currentDot && <Circle
  140. cx={center}
  141. cy={center}
  142. r={radius}
  143. fillOpacity={0}
  144. stroke={props.currentDot!.borderColor}
  145. transform={`rotate(${arc / (2 * Math.PI) * 360} ${center} ${center})`}
  146. strokeDasharray={`0,1000`}
  147. strokeWidth={lineWidth + 4}
  148. strokeLinecap="round"
  149. />
  150. }
  151. {
  152. props.currentDot && <Circle
  153. cx={center}
  154. cy={center}
  155. r={radius}
  156. fillOpacity={0}
  157. stroke={props.currentDot!.color}
  158. transform={`rotate(${arc / (2 * Math.PI) * 360} ${center} ${center})`}
  159. strokeDasharray={`0,1000`}
  160. strokeWidth={lineWidth}
  161. strokeLinecap="round"
  162. />
  163. }
  164. {
  165. props.dotList && props.dotList.map(item => {
  166. var time1 = item.timestamp ? new Date(item.timestamp) : new Date();
  167. var seconds1 = time1.getHours() * 3600 + time1.getMinutes() * 60 + time1.getSeconds();
  168. var arc1 = seconds1 / 86400 * 2 * Math.PI - Math.PI / 2.0;
  169. return <Circle
  170. cx={center}
  171. cy={center}
  172. r={radius}
  173. fillOpacity={0}
  174. stroke={item.borderColor}
  175. transform={`rotate(${arc1 / (2 * Math.PI) * 360} ${center} ${center})`}
  176. strokeDasharray={`0,1000`}
  177. strokeWidth={lineWidth + 6}
  178. strokeLinecap="round"
  179. />
  180. })
  181. }
  182. {
  183. props.dotList && props.dotList.map(item => {
  184. var time1 = item.timestamp ? new Date(item.timestamp) : new Date();
  185. var seconds1 = time1.getHours() * 3600 + time1.getMinutes() * 60 + time1.getSeconds();
  186. var arc1 = seconds1 / 86400 * 2 * Math.PI - Math.PI / 2.0;
  187. return <Circle
  188. cx={center}
  189. cy={center}
  190. r={radius}
  191. fillOpacity={0}
  192. stroke={item.color}
  193. transform={`rotate(${arc1 / (2 * Math.PI) * 360} ${center} ${center})`}
  194. strokeDasharray={`0,1000`}
  195. strokeWidth={lineWidth}
  196. strokeLinecap="round"
  197. />
  198. })
  199. }
  200. </Svg>
  201. }
  202. return <Svg width={(radius * 2 + lineWidth) + 6} height={(radius * 2 + lineWidth) + 6} fillOpacity={0}>
  203. {
  204. drawContent()
  205. }
  206. </Svg>
  207. // return <View style={{ width: 100, height: 100, backgroundColor: 'pink' }}></View>
  208. }