index.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import { __awaiter, __generator } from "tslib";
  2. import { useMemo, useRef, useState } from 'functional-mini/compat';
  3. import { useComponent, useEffect } from 'functional-mini/component';
  4. import '../_util/assert-component2';
  5. import { mountComponent } from '../_util/component';
  6. import { createCanvasContext } from '../_util/jsapi/create-canvas-context';
  7. import { getSystemInfo } from '../_util/jsapi/get-system-info';
  8. import { ProgressBarFunctionalProps } from './props';
  9. function requestAnimationFrame(fn) {
  10. setTimeout(fn, 16);
  11. }
  12. function toNumber(value, defaultValue) {
  13. if (typeof value === 'number') {
  14. return value;
  15. }
  16. if (typeof value === 'string') {
  17. var val = parseInt(value, 10);
  18. if (isNaN(val)) {
  19. return defaultValue;
  20. }
  21. return val;
  22. }
  23. return defaultValue;
  24. }
  25. var Progress = function (props) {
  26. var _a = useState(0), curProgress = _a[0], setCurProgress = _a[1];
  27. var canvasRequestRef = useRef(null);
  28. var _b = useState(100), canvasWidthState = _b[0], setCanvasWidthState = _b[1];
  29. function getDrawColor() {
  30. return __awaiter(this, void 0, void 0, function () {
  31. var strokeColor, trailColor, drawColor;
  32. return __generator(this, function (_a) {
  33. strokeColor = props.strokeColor, trailColor = props.trailColor;
  34. drawColor = {
  35. strokeColor: strokeColor || '#1677ff',
  36. trailColor: trailColor || '#F5F5F5',
  37. };
  38. return [2 /*return*/, drawColor];
  39. });
  40. });
  41. }
  42. function drawProgress(ctx, canvasWidth, color, rad) {
  43. ctx.beginPath();
  44. ctx.strokeStyle = color;
  45. ctx.lineWidth = toNumber(props.strokeWidth, 8);
  46. ctx.setLineCap('round');
  47. ctx.arc(canvasWidth / 2, canvasWidth / 2, canvasWidth / 2 - toNumber(props.strokeWidth, 8), -Math.PI / 2, -Math.PI / 2 + (rad / 360) * 2 * Math.PI, false);
  48. ctx.stroke();
  49. }
  50. function drawOrbit(ctx, canvasWidth, color) {
  51. ctx.beginPath();
  52. ctx.strokeStyle = color;
  53. ctx.lineWidth = toNumber(props.strokeWidth, 8);
  54. ctx.arc(canvasWidth / 2, canvasWidth / 2, canvasWidth / 2 - toNumber(props.strokeWidth, 8), 0, Math.PI * 2, false);
  55. ctx.stroke();
  56. }
  57. function clearCanvas(ctx, canvasWidth) {
  58. ctx.clearRect(0, 0, canvasWidth, canvasWidth);
  59. }
  60. var instance = useComponent();
  61. var canvasId = useMemo(function () {
  62. if (instance.$id) {
  63. return "ant-progress-canvas-".concat(instance.$id);
  64. }
  65. return "ant-progress-canvas";
  66. }, []);
  67. function getCanvasContext() {
  68. return __awaiter(this, void 0, void 0, function () {
  69. var ctx;
  70. return __generator(this, function (_a) {
  71. switch (_a.label) {
  72. case 0:
  73. ctx = canvasRequestRef.current;
  74. if (!ctx) return [3 /*break*/, 2];
  75. return [4 /*yield*/, ctx];
  76. case 1: return [2 /*return*/, _a.sent()];
  77. case 2:
  78. canvasRequestRef.current = createCanvasContext([canvasId, instance]);
  79. return [4 /*yield*/, canvasRequestRef.current];
  80. case 3:
  81. ctx = _a.sent();
  82. ctx.imageSmoothingEnabled = true;
  83. ctx.imageSmoothingQuality = 'high';
  84. return [2 /*return*/, ctx];
  85. }
  86. });
  87. });
  88. }
  89. function getCanvasWidth() {
  90. return __awaiter(this, void 0, void 0, function () {
  91. var systemInfo, pixelRatio, width;
  92. return __generator(this, function (_a) {
  93. switch (_a.label) {
  94. case 0: return [4 /*yield*/, getSystemInfo()];
  95. case 1:
  96. systemInfo = _a.sent();
  97. pixelRatio = systemInfo.pixelRatio;
  98. width = props.width;
  99. return [2 /*return*/, pixelRatio * width];
  100. }
  101. });
  102. });
  103. }
  104. function updateCanvasProgress(prev, targetPercent) {
  105. return __awaiter(this, void 0, void 0, function () {
  106. var drawColor, ctx, curRad, canvasWidth, targetRad, direction, draw;
  107. return __generator(this, function (_a) {
  108. switch (_a.label) {
  109. case 0: return [4 /*yield*/, getDrawColor()];
  110. case 1:
  111. drawColor = _a.sent();
  112. return [4 /*yield*/, getCanvasContext()];
  113. case 2:
  114. ctx = _a.sent();
  115. curRad = Math.floor((prev / 100) * 360);
  116. return [4 /*yield*/, getCanvasWidth()];
  117. case 3:
  118. canvasWidth = _a.sent();
  119. setCanvasWidthState(canvasWidth);
  120. targetRad = Math.floor((targetPercent / 100) * 360);
  121. direction = curRad < targetRad ? 1 : -1;
  122. draw = function () {
  123. if (curRad == targetRad)
  124. return;
  125. curRad = direction * props.speed + curRad;
  126. if (direction == -1) {
  127. curRad = Math.max(curRad, targetRad);
  128. }
  129. else {
  130. curRad = Math.min(curRad, targetRad);
  131. }
  132. clearCanvas(ctx, canvasWidth);
  133. drawOrbit(ctx, canvasWidth, drawColor.trailColor);
  134. drawProgress(ctx, canvasWidth, drawColor.strokeColor, curRad);
  135. ctx.draw(true);
  136. requestAnimationFrame(draw);
  137. };
  138. draw();
  139. return [2 /*return*/];
  140. }
  141. });
  142. });
  143. }
  144. useEffect(function () {
  145. var percent = +props.percent;
  146. if (isNaN(percent)) {
  147. percent = 0;
  148. }
  149. if (percent !== curProgress) {
  150. setCurProgress(percent > 100 ? 100 : percent < 0 ? 0 : percent);
  151. }
  152. if (props.type === 'circle') {
  153. updateCanvasProgress(curProgress, percent);
  154. }
  155. }, [props.type, props.speed, props.percent]);
  156. return {
  157. curProgress: curProgress,
  158. canvasWidth: canvasWidthState,
  159. canvasId: canvasId,
  160. };
  161. };
  162. mountComponent(Progress, ProgressBarFunctionalProps);