| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 | 
							- import { VantComponent } from '../common/component';
 
- import { isObj } from '../common/utils';
 
- import { BLUE, WHITE } from '../common/color';
 
- import { adaptor } from './canvas';
 
- function format(rate) {
 
-   return Math.min(Math.max(rate, 0), 100);
 
- }
 
- const PERIMETER = 2 * Math.PI;
 
- const BEGIN_ANGLE = -Math.PI / 2;
 
- const STEP = 1;
 
- VantComponent({
 
-   props: {
 
-     text: String,
 
-     lineCap: {
 
-       type: String,
 
-       value: 'round',
 
-     },
 
-     value: {
 
-       type: Number,
 
-       value: 0,
 
-       observer: 'reRender',
 
-     },
 
-     speed: {
 
-       type: Number,
 
-       value: 50,
 
-     },
 
-     size: {
 
-       type: Number,
 
-       value: 100,
 
-       observer() {
 
-         this.drawCircle(this.currentValue);
 
-       },
 
-     },
 
-     fill: String,
 
-     layerColor: {
 
-       type: String,
 
-       value: WHITE,
 
-     },
 
-     color: {
 
-       type: [String, Object],
 
-       value: BLUE,
 
-       observer() {
 
-         this.setHoverColor().then(() => {
 
-           this.drawCircle(this.currentValue);
 
-         });
 
-       },
 
-     },
 
-     type: {
 
-       type: String,
 
-       value: '',
 
-     },
 
-     strokeWidth: {
 
-       type: Number,
 
-       value: 4,
 
-     },
 
-     clockwise: {
 
-       type: Boolean,
 
-       value: true,
 
-     },
 
-   },
 
-   data: {
 
-     hoverColor: BLUE,
 
-   },
 
-   methods: {
 
-     getContext() {
 
-       const { type, size } = this.data;
 
-       if (type === '') {
 
-         const ctx = wx.createCanvasContext('van-circle', this);
 
-         return Promise.resolve(ctx);
 
-       }
 
-       const dpr = wx.getSystemInfoSync().pixelRatio;
 
-       return new Promise((resolve) => {
 
-         wx.createSelectorQuery()
 
-           .in(this)
 
-           .select('#van-circle')
 
-           .node()
 
-           .exec((res) => {
 
-             const canvas = res[0].node;
 
-             const ctx = canvas.getContext(type);
 
-             if (!this.inited) {
 
-               this.inited = true;
 
-               canvas.width = size * dpr;
 
-               canvas.height = size * dpr;
 
-               ctx.scale(dpr, dpr);
 
-             }
 
-             resolve(adaptor(ctx));
 
-           });
 
-       });
 
-     },
 
-     setHoverColor() {
 
-       const { color, size } = this.data;
 
-       if (isObj(color)) {
 
-         return this.getContext().then((context) => {
 
-           const LinearColor = context.createLinearGradient(size, 0, 0, 0);
 
-           Object.keys(color)
 
-             .sort((a, b) => parseFloat(a) - parseFloat(b))
 
-             .map((key) =>
 
-               LinearColor.addColorStop(parseFloat(key) / 100, color[key])
 
-             );
 
-           this.hoverColor = LinearColor;
 
-         });
 
-       }
 
-       this.hoverColor = color;
 
-       return Promise.resolve();
 
-     },
 
-     presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
 
-       const { strokeWidth, lineCap, clockwise, size } = this.data;
 
-       const position = size / 2;
 
-       const radius = position - strokeWidth / 2;
 
-       context.setStrokeStyle(strokeStyle);
 
-       context.setLineWidth(strokeWidth);
 
-       context.setLineCap(lineCap);
 
-       context.beginPath();
 
-       context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
 
-       context.stroke();
 
-       if (fill) {
 
-         context.setFillStyle(fill);
 
-         context.fill();
 
-       }
 
-     },
 
-     renderLayerCircle(context) {
 
-       const { layerColor, fill } = this.data;
 
-       this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
 
-     },
 
-     renderHoverCircle(context, formatValue) {
 
-       const { clockwise } = this.data;
 
-       // 结束角度
 
-       const progress = PERIMETER * (formatValue / 100);
 
-       const endAngle = clockwise
 
-         ? BEGIN_ANGLE + progress
 
-         : 3 * Math.PI - (BEGIN_ANGLE + progress);
 
-       this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle);
 
-     },
 
-     drawCircle(currentValue) {
 
-       const { size } = this.data;
 
-       this.getContext().then((context) => {
 
-         context.clearRect(0, 0, size, size);
 
-         this.renderLayerCircle(context);
 
-         const formatValue = format(currentValue);
 
-         if (formatValue !== 0) {
 
-           this.renderHoverCircle(context, formatValue);
 
-         }
 
-         context.draw();
 
-       });
 
-     },
 
-     reRender() {
 
-       // tofector 动画暂时没有想到好的解决方案
 
-       const { value, speed } = this.data;
 
-       if (speed <= 0 || speed > 1000) {
 
-         this.drawCircle(value);
 
-         return;
 
-       }
 
-       this.clearInterval();
 
-       this.currentValue = this.currentValue || 0;
 
-       this.interval = setInterval(() => {
 
-         if (this.currentValue !== value) {
 
-           if (this.currentValue < value) {
 
-             this.currentValue += STEP;
 
-           } else {
 
-             this.currentValue -= STEP;
 
-           }
 
-           this.drawCircle(this.currentValue);
 
-         } else {
 
-           this.clearInterval();
 
-         }
 
-       }, 1000 / speed);
 
-     },
 
-     clearInterval() {
 
-       if (this.interval) {
 
-         clearInterval(this.interval);
 
-         this.interval = null;
 
-       }
 
-     },
 
-   },
 
-   mounted() {
 
-     this.currentValue = this.data.value;
 
-     this.setHoverColor().then(() => {
 
-       this.drawCircle(this.currentValue);
 
-     });
 
-   },
 
-   destroyed() {
 
-     this.clearInterval();
 
-   },
 
- });
 
 
  |