index.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { use } from '../utils';
  2. import { raf, cancel } from '../utils/raf';
  3. import { BLUE, WHITE } from '../utils/color';
  4. var _use = use('circle'),
  5. sfc = _use[0],
  6. bem = _use[1];
  7. var PERIMETER = 3140;
  8. var PATH = 'M 530 530 m -500, 0 a 500, 500 0 1, 1 1000, 0 a 500, 500 0 1, 1 -1000, 0';
  9. function format(rate) {
  10. return Math.min(Math.max(rate, 0), 100);
  11. }
  12. export default sfc({
  13. props: {
  14. text: String,
  15. value: Number,
  16. speed: Number,
  17. size: {
  18. type: String,
  19. "default": '100px'
  20. },
  21. fill: {
  22. type: String,
  23. "default": 'none'
  24. },
  25. rate: {
  26. type: Number,
  27. "default": 100
  28. },
  29. layerColor: {
  30. type: String,
  31. "default": WHITE
  32. },
  33. color: {
  34. type: String,
  35. "default": BLUE
  36. },
  37. strokeWidth: {
  38. type: Number,
  39. "default": 40
  40. },
  41. clockwise: {
  42. type: Boolean,
  43. "default": true
  44. }
  45. },
  46. computed: {
  47. style: function style() {
  48. return {
  49. width: this.size,
  50. height: this.size
  51. };
  52. },
  53. layerStyle: function layerStyle() {
  54. var offset = PERIMETER * (100 - this.value) / 100;
  55. offset = this.clockwise ? offset : PERIMETER * 2 - offset;
  56. return {
  57. stroke: "" + this.color,
  58. strokeDashoffset: offset + "px",
  59. strokeWidth: this.strokeWidth + 1 + "px"
  60. };
  61. },
  62. hoverStyle: function hoverStyle() {
  63. return {
  64. fill: "" + this.fill,
  65. stroke: "" + this.layerColor,
  66. strokeWidth: this.strokeWidth + "px"
  67. };
  68. }
  69. },
  70. watch: {
  71. rate: {
  72. handler: function handler() {
  73. this.startTime = Date.now();
  74. this.startRate = this.value;
  75. this.endRate = format(this.rate);
  76. this.increase = this.endRate > this.startRate;
  77. this.duration = Math.abs((this.startRate - this.endRate) * 1000 / this.speed);
  78. if (this.speed) {
  79. cancel(this.rafId);
  80. this.rafId = raf(this.animate);
  81. } else {
  82. this.$emit('input', this.endRate);
  83. }
  84. },
  85. immediate: true
  86. }
  87. },
  88. methods: {
  89. animate: function animate() {
  90. var now = Date.now();
  91. var progress = Math.min((now - this.startTime) / this.duration, 1);
  92. var rate = progress * (this.endRate - this.startRate) + this.startRate;
  93. this.$emit('input', format(parseFloat(rate.toFixed(1))));
  94. if (this.increase ? rate < this.endRate : rate > this.endRate) {
  95. this.rafId = raf(this.animate);
  96. }
  97. }
  98. },
  99. render: function render(h) {
  100. return h("div", {
  101. "class": bem(),
  102. "style": this.style
  103. }, [h("svg", {
  104. "attrs": {
  105. "viewBox": "0 0 1060 1060"
  106. }
  107. }, [h("path", {
  108. "class": bem('hover'),
  109. "style": this.hoverStyle,
  110. "attrs": {
  111. "d": PATH
  112. }
  113. }), h("path", {
  114. "class": bem('layer'),
  115. "style": this.layerStyle,
  116. "attrs": {
  117. "d": PATH
  118. }
  119. })]), this.slots() || this.text && h("div", {
  120. "class": bem('text')
  121. }, [this.text])]);
  122. }
  123. });