index.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <template>
  2. <div :class="classes" :style="{ height: radius * 2 + 'px', width: radius * 2 + 'px' }">
  3. <svg viewBox="0 0 100 100">
  4. <defs>
  5. <linearGradient :id="refRandomId" x1="100%" y1="0%" x2="0%" y2="0%">
  6. <stop v-for="(item, index) in stop" :key="index" :offset="item.key" :stop-color="item.value"></stop>
  7. </linearGradient>
  8. </defs>
  9. <path class="nut-circleprogress-path" :style="pathStyle" :d="path" fill="none" :stroke-width="strokeWidth">
  10. >
  11. </path>
  12. <path
  13. class="nut-circleprogress-hover"
  14. :style="hoverStyle"
  15. :d="path"
  16. fill="none"
  17. :stroke="hoverColor"
  18. :stroke-linecap="strokeLinecap"
  19. :stroke-width="strokeWidth"
  20. ></path>
  21. </svg>
  22. <div class="nut-circleprogress-text">
  23. <slot></slot>
  24. <div v-if="!slotDefault">{{ progress }}%</div>
  25. </div>
  26. </div>
  27. </template>
  28. <script lang="ts">
  29. import { computed, useSlots } from 'vue';
  30. import { createComponent } from '@/packages/utils/create';
  31. import { isObject } from '@/packages/utils/util';
  32. const { componentName, create } = createComponent('circleprogress');
  33. export default create({
  34. props: {
  35. progress: {
  36. type: [Number, String],
  37. required: true
  38. },
  39. strokeWidth: {
  40. type: [Number, String],
  41. default: 5
  42. },
  43. radius: {
  44. type: [Number, String],
  45. default: 50
  46. },
  47. strokeLinecap: {
  48. type: String,
  49. default: 'round'
  50. },
  51. color: {
  52. type: [String, Object],
  53. default: ''
  54. },
  55. pathColor: {
  56. type: String,
  57. default: ''
  58. },
  59. clockwise: {
  60. type: Boolean,
  61. default: true
  62. }
  63. },
  64. setup(props, { emit }) {
  65. const slotDefault = !!useSlots().default;
  66. const refRandomId = Math.random().toString(36).slice(-8);
  67. const classes = computed(() => {
  68. const prefixCls = componentName;
  69. return {
  70. [prefixCls]: true
  71. };
  72. });
  73. const path = computed(() => {
  74. const isWise = props.clockwise ? 1 : 0;
  75. return `M 50 50 m 0 -45 a 45 45 0 1 ${isWise} 0 90 a 45 45 0 1, ${isWise} 0 -90`;
  76. });
  77. const hoverColor = computed(() => {
  78. return isObject(props.color) ? `url(#${refRandomId})` : props.color;
  79. });
  80. const hoverStyle = computed(() => {
  81. let perimeter = 283;
  82. let offset = (perimeter * Number(props.progress)) / 100;
  83. return {
  84. stroke: isObject(props.color) ? `url(#${refRandomId})` : props.color,
  85. strokeDasharray: `${offset}px ${perimeter}px`
  86. };
  87. });
  88. const pathStyle = computed(() => {
  89. return {
  90. stroke: props.pathColor
  91. };
  92. });
  93. const stop = computed(() => {
  94. if (!isObject(props.color)) {
  95. return;
  96. }
  97. let color = props.color;
  98. const colorArr = Object.keys(color).sort((a, b) => parseFloat(a) - parseFloat(b));
  99. let stopArr: object[] = [];
  100. colorArr.map((item, index) => {
  101. let obj = {
  102. key: '',
  103. value: ''
  104. };
  105. obj.key = item;
  106. obj.value = color[item];
  107. stopArr.push(obj);
  108. });
  109. return stopArr;
  110. });
  111. return {
  112. classes,
  113. hoverStyle,
  114. pathStyle,
  115. path,
  116. hoverColor,
  117. stop,
  118. slotDefault,
  119. refRandomId
  120. };
  121. }
  122. });
  123. </script>