c-progress-circle.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <template>
  2. <view class='container' :style="{width:size,height:size}">
  3. <view class="left">
  4. <view class="leftcircle" :style="leftcircleStyle">
  5. </view>
  6. </view>
  7. <view class="right">
  8. <view class="rightcircle" :style="rightcircleStyle"></view>
  9. </view>
  10. <view class="cneter-box">
  11. <slot>
  12. {{progress*100}}%
  13. </slot>
  14. </view>
  15. </view>
  16. </template>
  17. <script>
  18. /**
  19. * c-lockScreen 环形进度条
  20. * @property {Number} progress 进度 0-1 默认0
  21. * @property {String} color 进度条颜色 默认#3ec3c1
  22. * @property {String} size 进度条尺寸 单位rpx 默认200rpx
  23. * @property {String} boderWidth 边框宽度 单位rpx 默认200rpx
  24. * */
  25. export default {
  26. props:{
  27. progress: {
  28. type: Number,
  29. default: 0
  30. },
  31. color: {
  32. type: String,
  33. default: '#3ec3c1'
  34. },
  35. size: {
  36. type: String,
  37. default: "200rpx"
  38. },
  39. boderWidth:{
  40. type: String,
  41. default: "200rpx"
  42. }
  43. },
  44. computed:{
  45. leftcircleStyle(){
  46. return `border-width: calc(${this.boderWidth} * 0.1);
  47. border-bottom-color:${this.color};
  48. border-left-color:${this.color};
  49. transform: rotate(${this.leftAngle});
  50. `
  51. },
  52. rightcircleStyle(){
  53. return `border-width: calc(${this.boderWidth} * 0.1);
  54. border-top-color:${this.color};
  55. border-right-color:${this.color};
  56. transform: rotate(${this.rightAngle});`
  57. },
  58. rightAngle(){
  59. if (this.progress >= 0.5) {
  60. return 45+'deg'
  61. } else {
  62. return -135 + 180 * this.progress * 2+'deg'
  63. }
  64. },
  65. leftAngle(){
  66. if (this.progress < 0.5) {
  67. return -135+'deg'
  68. } else {
  69. return -315 + 180 * this.progress * 2+'deg'
  70. }
  71. }
  72. }
  73. }
  74. </script>
  75. <style lang="scss" scoped>
  76. view{
  77. box-sizing: border-box;
  78. }
  79. .container {
  80. display: flex;
  81. position: relative;
  82. // width: v-bind(size);
  83. // height: v-bind(size);
  84. .left {
  85. width: 50%;
  86. height: 100%;
  87. position: relative;
  88. overflow: hidden;
  89. top: 0;
  90. left: 0;
  91. .leftcircle {
  92. width: 200%;
  93. height: 100%;
  94. border-color:white;
  95. border-style: solid;
  96. position: absolute;
  97. border-radius: 50%;
  98. left: 0px;
  99. top: 0px;
  100. transition: transform 0.2s;
  101. //vue3
  102. // border-width: calc(v-bind(size) * 0.1);
  103. // border-bottom-color:v-bind(color);
  104. // border-left-color:v-bind(color);
  105. // transform: rotate(v-bind(leftAngle));
  106. // animation-name: circle_left;
  107. // animation-duration: 2s;
  108. // animation-timing-function: linear;
  109. // animation-iteration-count: infinite;
  110. }
  111. }
  112. .right {
  113. width: 50%;
  114. height: 100%;
  115. position: relative;
  116. overflow: hidden;
  117. top: 0;
  118. right: 0;
  119. }
  120. .rightcircle {
  121. width: 200%;
  122. height: 100%;
  123. border-radius: 50%;
  124. border-color:white;
  125. border-style: solid;
  126. position: absolute;
  127. right: 0px;
  128. top: 0px;
  129. // animation-name: circle_right;
  130. // animation-duration: 2s;
  131. // animation-timing-function: linear;
  132. // animation-iteration-count: infinite;
  133. transition: transform 0.2s;
  134. //vue3
  135. // border-width: calc(v-bind(size) * 0.1);
  136. // border-top-color:v-bind(color);
  137. // border-right-color:v-bind(color);
  138. // transform: rotate(v-bind(rightAngle));
  139. }
  140. .cneter-box{
  141. position: absolute;
  142. width: 100%;
  143. height: 100%;
  144. font-size: 24rpx;
  145. display: flex;
  146. align-items: center;
  147. justify-content: center;
  148. }
  149. }
  150. // @keyframes circle_right {
  151. // 0% {
  152. // transform: rotate(-135deg);
  153. // }
  154. // 50%,
  155. // 100% {
  156. // transform: rotate(45deg);
  157. // }
  158. // }
  159. // @keyframes circle_left {
  160. // 0%,
  161. // 50% {
  162. // transform: rotate(-135deg);
  163. // }
  164. // 100% {
  165. // transform: rotate(45deg);
  166. // }
  167. // }
  168. </style>