Circle.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. var __defProp = Object.defineProperty;
  2. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  3. var __getOwnPropNames = Object.getOwnPropertyNames;
  4. var __hasOwnProp = Object.prototype.hasOwnProperty;
  5. var __export = (target, all) => {
  6. for (var name2 in all)
  7. __defProp(target, name2, { get: all[name2], enumerable: true });
  8. };
  9. var __copyProps = (to, from, except, desc) => {
  10. if (from && typeof from === "object" || typeof from === "function") {
  11. for (let key of __getOwnPropNames(from))
  12. if (!__hasOwnProp.call(to, key) && key !== except)
  13. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  14. }
  15. return to;
  16. };
  17. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  18. var stdin_exports = {};
  19. __export(stdin_exports, {
  20. default: () => stdin_default
  21. });
  22. module.exports = __toCommonJS(stdin_exports);
  23. var import_vue = require("vue");
  24. var import_vue2 = require("vue");
  25. var import_use = require("@vant/use");
  26. var import_utils = require("../utils");
  27. const [name, bem] = (0, import_utils.createNamespace)("circle");
  28. let uid = 0;
  29. const format = (rate) => Math.min(Math.max(+rate, 0), 100);
  30. function getPath(clockwise, viewBoxSize) {
  31. const sweepFlag = clockwise ? 1 : 0;
  32. return `M ${viewBoxSize / 2} ${viewBoxSize / 2} m 0, -500 a 500, 500 0 1, ${sweepFlag} 0, 1000 a 500, 500 0 1, ${sweepFlag} 0, -1000`;
  33. }
  34. const circleProps = {
  35. text: String,
  36. size: import_utils.numericProp,
  37. fill: (0, import_utils.makeStringProp)("none"),
  38. rate: (0, import_utils.makeNumericProp)(100),
  39. speed: (0, import_utils.makeNumericProp)(0),
  40. color: [String, Object],
  41. clockwise: import_utils.truthProp,
  42. layerColor: String,
  43. currentRate: (0, import_utils.makeNumberProp)(0),
  44. strokeWidth: (0, import_utils.makeNumericProp)(40),
  45. strokeLinecap: String,
  46. startPosition: (0, import_utils.makeStringProp)("top")
  47. };
  48. var stdin_default = (0, import_vue2.defineComponent)({
  49. name,
  50. props: circleProps,
  51. emits: ["update:currentRate"],
  52. setup(props, {
  53. emit,
  54. slots
  55. }) {
  56. const id = `van-circle-${uid++}`;
  57. const viewBoxSize = (0, import_vue2.computed)(() => +props.strokeWidth + 1e3);
  58. const path = (0, import_vue2.computed)(() => getPath(props.clockwise, viewBoxSize.value));
  59. const svgStyle = (0, import_vue2.computed)(() => {
  60. const ROTATE_ANGLE_MAP = {
  61. top: 0,
  62. right: 90,
  63. bottom: 180,
  64. left: 270
  65. };
  66. const angleValue = ROTATE_ANGLE_MAP[props.startPosition];
  67. if (angleValue) {
  68. return {
  69. transform: `rotate(${angleValue}deg)`
  70. };
  71. }
  72. });
  73. (0, import_vue2.watch)(() => props.rate, (rate) => {
  74. let rafId;
  75. const startTime = Date.now();
  76. const startRate = props.currentRate;
  77. const endRate = format(rate);
  78. const duration = Math.abs((startRate - endRate) * 1e3 / +props.speed);
  79. const animate = () => {
  80. const now = Date.now();
  81. const progress = Math.min((now - startTime) / duration, 1);
  82. const rate2 = progress * (endRate - startRate) + startRate;
  83. emit("update:currentRate", format(parseFloat(rate2.toFixed(1))));
  84. if (endRate > startRate ? rate2 < endRate : rate2 > endRate) {
  85. rafId = (0, import_use.raf)(animate);
  86. }
  87. };
  88. if (props.speed) {
  89. if (rafId) {
  90. (0, import_use.cancelRaf)(rafId);
  91. }
  92. rafId = (0, import_use.raf)(animate);
  93. } else {
  94. emit("update:currentRate", endRate);
  95. }
  96. }, {
  97. immediate: true
  98. });
  99. const renderHover = () => {
  100. const PERIMETER = 3140;
  101. const {
  102. strokeWidth,
  103. currentRate,
  104. strokeLinecap
  105. } = props;
  106. const offset = PERIMETER * currentRate / 100;
  107. const color = (0, import_utils.isObject)(props.color) ? `url(#${id})` : props.color;
  108. const style = {
  109. stroke: color,
  110. strokeWidth: `${+strokeWidth + 1}px`,
  111. strokeLinecap,
  112. strokeDasharray: `${offset}px ${PERIMETER}px`
  113. };
  114. return (0, import_vue.createVNode)("path", {
  115. "d": path.value,
  116. "style": style,
  117. "class": bem("hover"),
  118. "stroke": color
  119. }, null);
  120. };
  121. const renderLayer = () => {
  122. const style = {
  123. fill: props.fill,
  124. stroke: props.layerColor,
  125. strokeWidth: `${props.strokeWidth}px`
  126. };
  127. return (0, import_vue.createVNode)("path", {
  128. "class": bem("layer"),
  129. "style": style,
  130. "d": path.value
  131. }, null);
  132. };
  133. const renderGradient = () => {
  134. const {
  135. color
  136. } = props;
  137. if (!(0, import_utils.isObject)(color)) {
  138. return;
  139. }
  140. const Stops = Object.keys(color).sort((a, b) => parseFloat(a) - parseFloat(b)).map((key, index) => (0, import_vue.createVNode)("stop", {
  141. "key": index,
  142. "offset": key,
  143. "stop-color": color[key]
  144. }, null));
  145. return (0, import_vue.createVNode)("defs", null, [(0, import_vue.createVNode)("linearGradient", {
  146. "id": id,
  147. "x1": "100%",
  148. "y1": "0%",
  149. "x2": "0%",
  150. "y2": "0%"
  151. }, [Stops])]);
  152. };
  153. const renderText = () => {
  154. if (slots.default) {
  155. return slots.default();
  156. }
  157. if (props.text) {
  158. return (0, import_vue.createVNode)("div", {
  159. "class": bem("text")
  160. }, [props.text]);
  161. }
  162. };
  163. return () => (0, import_vue.createVNode)("div", {
  164. "class": bem(),
  165. "style": (0, import_utils.getSizeStyle)(props.size)
  166. }, [(0, import_vue.createVNode)("svg", {
  167. "viewBox": `0 0 ${viewBoxSize.value} ${viewBoxSize.value}`,
  168. "style": svgStyle.value
  169. }, [renderGradient(), renderLayer(), renderHover()]), renderText()]);
  170. }
  171. });