index.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <template>
  2. <uni-shadow-root class="weapp-lib-circle-index"><view class="van-circle">
  3. <canvas class="van-circle__canvas" :type="type" :style="'width: '+(utils.addUnit(size))+';height:'+(utils.addUnit(size))" id="van-circle" canvas-id="van-circle"></canvas>
  4. <view v-if="(!text)" class="van-circle__text">
  5. <slot></slot>
  6. </view>
  7. <cover-view v-else class="van-circle__text">{{ text }}</cover-view>
  8. </view></uni-shadow-root>
  9. </template>
  10. <wxs src="../wxs/utils.wxs" module="utils"></wxs>
  11. <script>
  12. global['__wxRoute'] = 'weapp/lib/circle/index'
  13. "use strict";
  14. Object.defineProperty(exports, "__esModule", { value: true });
  15. var color_1 = require("../common/color");
  16. var component_1 = require("../common/component");
  17. var utils_1 = require("../common/utils");
  18. var validator_1 = require("../common/validator");
  19. var version_1 = require("../common/version");
  20. var canvas_1 = require("./canvas");
  21. function format(rate) {
  22. return Math.min(Math.max(rate, 0), 100);
  23. }
  24. var PERIMETER = 2 * Math.PI;
  25. var BEGIN_ANGLE = -Math.PI / 2;
  26. var STEP = 1;
  27. (0, component_1.VantComponent)({
  28. props: {
  29. text: String,
  30. lineCap: {
  31. type: String,
  32. value: 'round',
  33. },
  34. value: {
  35. type: Number,
  36. value: 0,
  37. observer: 'reRender',
  38. },
  39. speed: {
  40. type: Number,
  41. value: 50,
  42. },
  43. size: {
  44. type: Number,
  45. value: 100,
  46. observer: function () {
  47. this.drawCircle(this.currentValue);
  48. },
  49. },
  50. fill: String,
  51. layerColor: {
  52. type: String,
  53. value: color_1.WHITE,
  54. },
  55. color: {
  56. type: null,
  57. value: color_1.BLUE,
  58. observer: function () {
  59. var _this = this;
  60. this.setHoverColor().then(function () {
  61. _this.drawCircle(_this.currentValue);
  62. });
  63. },
  64. },
  65. type: {
  66. type: String,
  67. value: '',
  68. },
  69. strokeWidth: {
  70. type: Number,
  71. value: 4,
  72. },
  73. clockwise: {
  74. type: Boolean,
  75. value: true,
  76. },
  77. },
  78. data: {
  79. hoverColor: color_1.BLUE,
  80. },
  81. methods: {
  82. getContext: function () {
  83. var _this = this;
  84. var _a = this.data, type = _a.type, size = _a.size;
  85. if (type === '' || !(0, version_1.canIUseCanvas2d)()) {
  86. var ctx = wx.createCanvasContext('van-circle', this);
  87. return Promise.resolve(ctx);
  88. }
  89. var dpr = (0, utils_1.getSystemInfoSync)().pixelRatio;
  90. return new Promise(function (resolve) {
  91. wx.createSelectorQuery()
  92. .in(_this)
  93. .select('#van-circle')
  94. .node()
  95. .exec(function (res) {
  96. var canvas = res[0].node;
  97. var ctx = canvas.getContext(type);
  98. if (!_this.inited) {
  99. _this.inited = true;
  100. canvas.width = size * dpr;
  101. canvas.height = size * dpr;
  102. ctx.scale(dpr, dpr);
  103. }
  104. resolve((0, canvas_1.adaptor)(ctx));
  105. });
  106. });
  107. },
  108. setHoverColor: function () {
  109. var _this = this;
  110. var _a = this.data, color = _a.color, size = _a.size;
  111. if ((0, validator_1.isObj)(color)) {
  112. return this.getContext().then(function (context) {
  113. var LinearColor = context.createLinearGradient(size, 0, 0, 0);
  114. Object.keys(color)
  115. .sort(function (a, b) { return parseFloat(a) - parseFloat(b); })
  116. .map(function (key) {
  117. return LinearColor.addColorStop(parseFloat(key) / 100, color[key]);
  118. });
  119. _this.hoverColor = LinearColor;
  120. });
  121. }
  122. this.hoverColor = color;
  123. return Promise.resolve();
  124. },
  125. presetCanvas: function (context, strokeStyle, beginAngle, endAngle, fill) {
  126. var _a = this.data, strokeWidth = _a.strokeWidth, lineCap = _a.lineCap, clockwise = _a.clockwise, size = _a.size;
  127. var position = size / 2;
  128. var radius = position - strokeWidth / 2;
  129. context.setStrokeStyle(strokeStyle);
  130. context.setLineWidth(strokeWidth);
  131. context.setLineCap(lineCap);
  132. context.beginPath();
  133. context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
  134. context.stroke();
  135. if (fill) {
  136. context.setFillStyle(fill);
  137. context.fill();
  138. }
  139. },
  140. renderLayerCircle: function (context) {
  141. var _a = this.data, layerColor = _a.layerColor, fill = _a.fill;
  142. this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
  143. },
  144. renderHoverCircle: function (context, formatValue) {
  145. var clockwise = this.data.clockwise;
  146. // 结束角度
  147. var progress = PERIMETER * (formatValue / 100);
  148. var endAngle = clockwise
  149. ? BEGIN_ANGLE + progress
  150. : 3 * Math.PI - (BEGIN_ANGLE + progress);
  151. this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle);
  152. },
  153. drawCircle: function (currentValue) {
  154. var _this = this;
  155. var size = this.data.size;
  156. this.getContext().then(function (context) {
  157. context.clearRect(0, 0, size, size);
  158. _this.renderLayerCircle(context);
  159. var formatValue = format(currentValue);
  160. if (formatValue !== 0) {
  161. _this.renderHoverCircle(context, formatValue);
  162. }
  163. context.draw();
  164. });
  165. },
  166. reRender: function () {
  167. var _this = this;
  168. // tofector 动画暂时没有想到好的解决方案
  169. var _a = this.data, value = _a.value, speed = _a.speed;
  170. if (speed <= 0 || speed > 1000) {
  171. this.drawCircle(value);
  172. return;
  173. }
  174. this.clearMockInterval();
  175. this.currentValue = this.currentValue || 0;
  176. var run = function () {
  177. _this.interval = setTimeout(function () {
  178. if (_this.currentValue !== value) {
  179. if (Math.abs(_this.currentValue - value) < STEP) {
  180. _this.currentValue = value;
  181. }
  182. else if (_this.currentValue < value) {
  183. _this.currentValue += STEP;
  184. }
  185. else {
  186. _this.currentValue -= STEP;
  187. }
  188. _this.drawCircle(_this.currentValue);
  189. run();
  190. }
  191. else {
  192. _this.clearMockInterval();
  193. }
  194. }, 1000 / speed);
  195. };
  196. run();
  197. },
  198. clearMockInterval: function () {
  199. if (this.interval) {
  200. clearTimeout(this.interval);
  201. this.interval = null;
  202. }
  203. },
  204. },
  205. mounted: function () {
  206. var _this = this;
  207. this.currentValue = this.data.value;
  208. this.setHoverColor().then(function () {
  209. _this.drawCircle(_this.currentValue);
  210. });
  211. },
  212. destroyed: function () {
  213. this.clearMockInterval();
  214. },
  215. });
  216. export default global['__wxComponents']['weapp/lib/circle/index']
  217. </script>
  218. <style platform="mp-weixin">
  219. @import '../common/index.css';.van-circle{display:inline-block;position:relative;text-align:center}.van-circle__text{color:var(--circle-text-color,#323233);left:0;position:absolute;top:50%;transform:translateY(-50%);width:100%}
  220. </style>