use-ring.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <template>
  2. <view class="use-ring pos-r">
  3. <view class="circle-ring pos-r">
  4. <view class="circle-left" :style="circleLeftCss" @transitionend="leftSuccess"></view>
  5. <view class="circle-right" :style="circleRightCss" @transitionend="rightSuccess"></view>
  6. <view class="circle-bottom-left"></view>
  7. <view class="circle-bottom-right"></view>
  8. </view>
  9. <view class="pos-a pos-tl-c ft-white">
  10. <slot />
  11. </view>
  12. </view>
  13. </template>
  14. <script>
  15. export default {
  16. props: {
  17. value: {
  18. type: [Number, String],
  19. default: 0
  20. },
  21. max: {
  22. type: [Number, String],
  23. default: 100
  24. },
  25. activeColor: {
  26. type: String,
  27. default: '#ffbc49'
  28. },
  29. baseColor: {
  30. type: String,
  31. default: '#fff'
  32. }
  33. },
  34. data() {
  35. return {
  36. circleLeftCss: '',
  37. circleRightCss: '',
  38. type: 'right'
  39. }
  40. },
  41. methods: {
  42. draw(val) {
  43. if (val !== 0) {
  44. val = val || this.value;
  45. }
  46. const percent = val / this.max;
  47. if (percent <= 0.5) {
  48. this.circleRightCss = `transform: rotate(${percent * 360}deg)`;
  49. this.type = 'right';
  50. } else {
  51. this.circleRightCss =
  52. `transform: rotate(180deg); transition: opacity 0s step-end 1s, transform 1s linear; opacity: 0`;
  53. this.circleLeftCss =
  54. `transition: transform ${(percent - 0.5) / 0.5}s linear 1s; transform: rotate(${percent * 360 - 180}deg)`;
  55. this.type = 'left';
  56. }
  57. },
  58. leftSuccess() {
  59. if (this.type == 'left') {
  60. this.$emit('success');
  61. }
  62. },
  63. rightSuccess() {
  64. if (this.type == 'right') {
  65. this.$emit('success');
  66. }
  67. }
  68. }
  69. }
  70. </script>
  71. <style lang="scss">
  72. .use-ring {
  73. .circle-ring {
  74. width: 200rpx;
  75. height: 200rpx;
  76. -webkit-mask: radial-gradient(transparent 86rpx, #fff 88rpx);
  77. overflow: hidden;
  78. border-radius: 50%;
  79. view {
  80. width: 50%;
  81. height: 100%;
  82. position: absolute;
  83. }
  84. }
  85. .circle-left {
  86. background: #fff;
  87. transform-origin: 100% 50%;
  88. left: 0;
  89. z-index: 0;
  90. }
  91. .circle-right {
  92. background: #fff;
  93. transition: transform 1s linear;
  94. transform-origin: 0% 50%;
  95. right: 0;
  96. z-index: 2;
  97. }
  98. .circle-bottom-left {
  99. background: #ffbc49;
  100. left: 0;
  101. z-index: -1;
  102. }
  103. .circle-bottom-right {
  104. background: #ffbc49;
  105. right: 0;
  106. z-index: 1;
  107. }
  108. }
  109. </style>