ProgressSvg.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import type { IFinal } from "../../api/Channel";
  2. interface IWidget {
  3. data?: IFinal[];
  4. width?: number;
  5. }
  6. const ProgressSvgWidget = ({ data, width = 300 }: IWidget) => {
  7. //绘制句子进度
  8. if (typeof data === "undefined" || data.length === 0) {
  9. return <></>;
  10. }
  11. //进度
  12. let svg_width = 0;
  13. if (data) {
  14. for (const iterator of data) {
  15. svg_width += iterator[0];
  16. }
  17. }
  18. const svg_height = svg_width / 10;
  19. let curr_x = 0;
  20. let finished = 0;
  21. const innerBar = data?.map((item, id) => {
  22. const stroke_width = item[0];
  23. curr_x += stroke_width;
  24. finished += item[1] ? stroke_width : 0;
  25. return (
  26. <rect
  27. key={id}
  28. x={curr_x - stroke_width}
  29. y={0}
  30. height={svg_height}
  31. width={stroke_width}
  32. fill={item[1] ? "url(#grad1)" : "url(#grad2)"}
  33. />
  34. );
  35. });
  36. const finishedBar = (
  37. <rect
  38. key="2"
  39. x={0}
  40. y={svg_height / 2 - svg_height / 20}
  41. width={finished}
  42. height={svg_height / 10}
  43. style={{ strokeWidth: 0, fill: "rgb(100, 100, 228)" }}
  44. />
  45. );
  46. const progress = (
  47. <svg viewBox={`0 0 ${svg_width} ${svg_height} `} width={"100%"}>
  48. <defs>
  49. <linearGradient key="1" id="grad1" x1="0%" y1="0%" x2="0%" y2="100%">
  50. <stop
  51. key="1"
  52. offset="0%"
  53. style={{ stopColor: "rgb(0,180,0)", stopOpacity: 1 }}
  54. />
  55. <stop
  56. key="2"
  57. offset="50%"
  58. style={{ stopColor: "rgb(255,255,255)", stopOpacity: 0.5 }}
  59. />
  60. <stop
  61. key="3"
  62. offset="100%"
  63. style={{ stopColor: "rgb(0,180,0)", stopOpacity: 1 }}
  64. />
  65. </linearGradient>
  66. <linearGradient key="2" id="grad2" x1="0%" y1="0%" x2="0%" y2="100%">
  67. <stop
  68. key="1"
  69. offset="0%"
  70. style={{ stopColor: "rgb(180,180,180)", stopOpacity: 1 }}
  71. />
  72. <stop
  73. key="2"
  74. offset="50%"
  75. style={{ stopColor: "rgb(255,255,255)", stopOpacity: 0.5 }}
  76. />
  77. <stop
  78. key="3"
  79. offset="100%"
  80. style={{ stopColor: "rgb(180,180,180)", stopOpacity: 1 }}
  81. />
  82. </linearGradient>
  83. </defs>
  84. {innerBar}
  85. {finishedBar}
  86. </svg>
  87. );
  88. return <div style={{ width: width }}>{progress}</div>;
  89. };
  90. export default ProgressSvgWidget;