progress.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <view class="progress_box">
  3. <canvas class="progress_bg" canvas-id="cpbg" :style="{ width: progress_width + 'px', height: progress_height + 'px' }"></canvas>
  4. <canvas class="progress_bar" canvas-id="cpbar" :style="{ width: progress_width + 'px', height: progress_height + 'px' }"></canvas>
  5. <view class="progress_info">
  6. <view class="info-number">{{ progress_txt }}/{{ progress_total }}</view>
  7. <view class="info-text">每日完成占比</view>
  8. </view>
  9. </view>
  10. </template>
  11. <script>
  12. /**
  13. * circleProgress 自己写的环形进度条
  14. * @property {String Number} value 圆环进度百分比值,为数值类型,0-100(默认必传).
  15. * @property {String Number} progress_time 圆环进度总时间
  16. * @property {String Number} border_width 圆环边框宽度
  17. * @property {String Number} progress_width 圆环宽度(建议宽高一致)
  18. * @property {String Number} progress_height 圆环高度(建议宽高一致)
  19. * @property {String} bg_color 圆环的背景色
  20. * @property {String} start_color 圆环开始渐变色
  21. * @property {String} bg_color 圆环结束渐变色
  22. */
  23. export default {
  24. props: {
  25. value: {
  26. type: Number,
  27. default: 25,
  28. required: true
  29. },
  30. progress_time: {
  31. type: Number,
  32. default: 0
  33. },
  34. progress_width: {
  35. type: Number,
  36. default: 170
  37. },
  38. progress_height: {
  39. type: Number,
  40. default: 120
  41. },
  42. border_width: {
  43. type: Number,
  44. default: 10
  45. },
  46. bg_color: {
  47. type: String,
  48. default: '#CCCCCC'
  49. },
  50. start_color: {
  51. type: String,
  52. default: '#2A82E4'
  53. },
  54. end_color: {
  55. type: String,
  56. default: '#2A82E4'
  57. },
  58. progress_txt: {
  59. type: Number,
  60. default: 0
  61. },
  62. progress_total: {
  63. type: Number,
  64. default: 0
  65. }
  66. },
  67. data() {
  68. return {
  69. percent: 0 // 保存进度值的变化前后值,用于比较用
  70. }
  71. },
  72. mounted() {
  73. this.drawProgressbg()
  74. this.drawCircle(this.value)
  75. },
  76. methods: {
  77. // 背景
  78. drawProgressbg: function() {
  79. // 自定义组件实例 this ,表示在这个自定义组件下查找拥有 canvas-id 的 <canvas/>
  80. let ctx = uni.createCanvasContext('cpbg', this)
  81. ctx.setLineWidth(this.border_width)
  82. ctx.setStrokeStyle(this.bg_color)
  83. ctx.setLineCap('round')
  84. ctx.beginPath()
  85. ctx.arc(75, 75, 60, 0.99 * Math.PI, 0.01 * Math.PI, false)
  86. ctx.stroke()
  87. ctx.draw()
  88. },
  89. // 画圆(递归调用)
  90. drawCircle: function(step) {
  91. if (step === 0) return
  92. let time = Math.floor(this.progress_time / 100)
  93. let ctx = uni.createCanvasContext('cpbar', this)
  94. let gradient = ctx.createLinearGradient(28, 55, 192, 55)
  95. gradient.addColorStop('0', this.start_color)
  96. gradient.addColorStop('1.0', this.end_color)
  97. ctx.setLineWidth(this.border_width)
  98. ctx.setStrokeStyle(gradient)
  99. ctx.setLineCap('round')
  100. ctx.beginPath()
  101. step = 0.01 * step + 0.99
  102. if (step === 1) {
  103. step = 0.99
  104. }
  105. if (step >= 2) {
  106. step = step % 2
  107. }
  108. if (step === 1.99) {
  109. step = 0.01
  110. }
  111. ctx.arc(75, 75, 60, 0.99 * Math.PI, step * Math.PI, false)
  112. ctx.stroke()
  113. ctx.draw()
  114. if (this.value > this.percent) {
  115. this.percent++
  116. setTimeout(() => {
  117. this.drawCircle(this.percent)
  118. }, time)
  119. }
  120. }
  121. }
  122. }
  123. </script>
  124. <style>
  125. .progress_box {
  126. position: relative;
  127. width: 100%;
  128. height: 100%;
  129. display: flex;
  130. align-items: center;
  131. justify-content: center;
  132. text-align: center;
  133. }
  134. .progress_bg {
  135. position: absolute;
  136. }
  137. .progress_info {
  138. position: absolute;
  139. top: 45px;
  140. left: 15px;
  141. width: 120px;
  142. height: 50px;
  143. }
  144. .info-number {
  145. font-weight: bold;
  146. }
  147. .info-text {
  148. color: #a6a6a6;
  149. }
  150. </style>