circle-progress-bar.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <template>
  2. <view class="circle-progress-bar" :style="{
  3. width: r_size + 'px',
  4. height: r_size + 'px',
  5. padding: bw_upx + 'px',
  6. background: border_color
  7. }">
  8. <view class="content1" :style="{ background: background }">
  9. <view class="inner">
  10. <slot :pro="pro"></slot>
  11. </view>
  12. </view>
  13. <view class="bar" :class="{ animate: animate }" :style="{ transform: `rotate(${start * 360}deg)` }">
  14. <view class="back n1" v-show="show_back" :style="{ background: border_color, transform: `rotate(${(pro - 0.5) * 360}deg)` }"></view>
  15. <view class="back n1" v-show="show_back" :style="{ background: border_color, 'z-index': 3 }"></view>
  16. <view class="mask n1" :style="{ background: border_back_color, transform: `rotate(${pro * 360}deg)` }"></view>
  17. <view class="mask n2" :style="{ background: border_back_color }"></view>
  18. <view class="point s"
  19. :style="{
  20. width: bw_upx + 'px',
  21. height: bw_upx + 'px',
  22. left: `calc(50% - ${bw_upx / 2}px)`,
  23. background: border_color,
  24. }"></view>
  25. <view class="point e"
  26. :style="{
  27. width: bw_upx + 'px',
  28. height: bw_upx + 'px',
  29. left: `calc(50% - ${bw_upx / 2}px)`,
  30. transform: `rotate(${pro * 360}deg)`,
  31. 'transform-origin': `${bw_upx / 2}px ${size_upx / 2}px`,
  32. background: border_color,
  33. }"></view>
  34. </view>
  35. </view>
  36. </template>
  37. <script>
  38. export default {
  39. name:"circle-progress-bar",
  40. props:{
  41. //进度 0-1
  42. pro: {
  43. type: Number,
  44. default: 0,
  45. },
  46. //起始位置 0-1
  47. start: {
  48. type: Number,
  49. default: 0,
  50. },
  51. //圆形大小
  52. size: {
  53. type: Number,
  54. default: 100
  55. },
  56. //线宽度
  57. border_width: {
  58. type: Number,
  59. default: 5
  60. },
  61. //线颜色
  62. border_color: {
  63. type: String,
  64. default: '#07C160',
  65. },
  66. //线背景色
  67. border_back_color: {
  68. type: String,
  69. default: '#fff',
  70. },
  71. //中心内容背景色
  72. background: {
  73. type: String,
  74. default: '#FFF',
  75. },
  76. //是否启用动画
  77. animate:{
  78. type: Boolean,
  79. default: true,
  80. }
  81. },
  82. data() {
  83. return {
  84. prev_pro: 0,
  85. };
  86. },
  87. watch:{
  88. pro(val, pval) {
  89. this.prev_pro = pval;
  90. }
  91. },
  92. computed:{
  93. r_size() {
  94. return this.size_upx - (2 * this.bw_upx);
  95. },
  96. size_upx() {
  97. return uni.upx2px(this.size)
  98. },
  99. bw_upx() {
  100. return uni.upx2px(this.border_width)
  101. },
  102. show_back() {
  103. return this.pro > 0.5 || (this.pro == 0.5 && this.prev_pro > this.pro)
  104. }
  105. }
  106. }
  107. </script>
  108. <style lang="scss">
  109. .circle-progress-bar{
  110. border-radius: 50%;
  111. overflow: hidden;
  112. position: relative;
  113. }
  114. .content1, .bar{
  115. height: 100%;
  116. width: 100%;
  117. }
  118. .content1{
  119. border-radius: 50%;
  120. overflow: hidden;
  121. position: relative;
  122. z-index: 5;
  123. }
  124. .inner{
  125. position: absolute;
  126. left: 50%;
  127. top: 50%;
  128. transform: translate(-50%, -50%);
  129. }
  130. .bar, .mask, .back, .point {
  131. position: absolute;
  132. }
  133. .bar{
  134. top: 0upx;
  135. left: 0upx;
  136. }
  137. .mask, .back{
  138. top: 0upx;
  139. width: 50%;
  140. height: 100%;
  141. }
  142. .n1{
  143. right: 0upx;
  144. transform-origin: 0% 50%;
  145. z-index: 2;
  146. }
  147. .n2{
  148. left: 0upx;
  149. z-index: 1;
  150. }
  151. .point{
  152. z-index: 3;
  153. top: 0upx;
  154. border-radius: 50%;
  155. }
  156. .bar.animate {
  157. &, .mask, .back, .point {
  158. transition: transform 0.3s;
  159. }
  160. }
  161. </style>