123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- <template>
- <view class="tui-circular-container" :style="{ width: diam + 'px', height: (height || diam) + 'px' }">
- <canvas
- :start="percent"
- :change:start="parse.initDraw"
- :data-width="diam"
- :data-height="height"
- :data-lineWidth="lineWidth"
- :data-lineCap="lineCap"
- :data-fontSize="fontSize"
- :data-fontColor="fontColor"
- :data-fontShow="fontShow"
- :data-percentText="percentText"
- :data-defaultShow="defaultShow"
- :data-defaultColor="defaultColor"
- :data-progressColor="progressColor"
- :data-gradualColor="gradualColor"
- :data-sAngle="sAngle"
- :data-counterclockwise="counterclockwise"
- :data-multiple="multiple"
- :data-speed="speed"
- :data-activeMode="activeMode"
- :data-cid="progressCanvasId"
- :canvas-id="progressCanvasId"
- :class="[progressCanvasId]"
- :style="{ width: diam + 'px', height: (height || diam) + 'px' }"
- ></canvas>
- <slot></slot>
- </view>
- </template>
- <script module="parse" lang="renderjs">
- export default {
- methods:{
- format(str){
- if(!str) return str;
- return str.replace(/\"/g, "");
- },
- bool(str){
- return str==='true' || str==true ? true:false
- },
-
- initDraw(percentage, oldPercentage, owner, ins) {
- let state=ins.getState();
- let res=ins.getDataset();
- const activeMode=this.format(res.activemode);
- let start = activeMode === 'backwards' ? 0 : (state.startPercentage || 0);
- if(!state.progressContext || !state.canvas){
- const width = res.width;
- const height = res.height==0?res.width:res.height;
- let ele=`.${res.cid}>canvas`
- const canvas = document.querySelectorAll(this.format(ele))[0];
- const ctx = canvas.getContext('2d');
-
-
-
-
-
-
- state.progressContext=ctx;
- state.canvas=canvas;
- this.drawProgressCircular(start, ctx, canvas,percentage,res,state,owner);
- }else{
- this.drawProgressCircular(start, state.progressContext, state.canvas,percentage,res,state,owner);
- }
- },
-
- drawDefaultCircular(ctx, canvas,res) {
-
- let sangle=Number(res.sangle) * Math.PI
- let eAngle = Math.PI * (res.height!=0 ? 1 : 2) + sangle;
- this.drawArc(ctx, eAngle,this.format(res.defaultcolor),res);
- },
- drawPercentage(ctx, percentage,res) {
- ctx.save();
- ctx.beginPath();
- ctx.fillStyle = this.format(res.fontcolor);
- ctx.font = res.fontsize + "px Arial";
- ctx.textAlign = "center";
- ctx.textBaseline = "middle";
- let radius = res.width / 2;
- let percenttext=this.format(res.percenttext)
- if (!percenttext) {
- let multiple=Number(res.multiple)
- percentage = this.bool(res.counterclockwise) ? 100 - percentage * multiple : percentage * multiple;
- percentage = percentage.toFixed(0) + "%"
- } else {
- percentage = percenttext
- }
- ctx.fillText(percentage, radius, radius);
- ctx.stroke();
- ctx.restore();
- },
-
- drawProgressCircular(startPercentage, ctx, canvas,percentage,res,state,owner) {
- if (!ctx || !canvas) return;
- let that=this
- let gradient = ctx.createLinearGradient(0, 0, Number(res.width), 0);
- gradient.addColorStop(0, this.format(res.progresscolor));
- let gradualColor=this.format(res.gradualcolor)
- if (gradualColor) {
- gradient.addColorStop('1', gradualColor);
- }
- let requestId = null
- let renderLoop = () => {
- drawFrame((res) => {
- if (res) {
- requestId = requestAnimationFrame(renderLoop)
- } else {
- cancelAnimationFrame(requestId)
- requestId = null;
- renderLoop = null;
- }
- })
- }
- requestId = requestAnimationFrame(renderLoop)
- function drawFrame(callback) {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- if (that.bool(res.defaultshow)) {
- that.drawDefaultCircular(ctx, canvas,res)
- }
- if (that.bool(res.fontshow)) {
- that.drawPercentage(ctx, startPercentage,res);
- }
- if (percentage === 0 || (that.bool(res.counterclockwise) && startPercentage === 100)) return;
- let sangle=Number(res.sangle) * Math.PI
- let eAngle = ((2 * Math.PI) / 100) * startPercentage + sangle;
- that.drawArc(ctx, eAngle, gradient,res);
- owner.callMethod('change', {
- percentage:startPercentage
- })
- if (startPercentage >= percentage) {
- state.startPercentage=startPercentage;
- owner.callMethod('end', {
- canvasId: that.format(res.canvasid)
- })
- cancelAnimationFrame(requestId)
- callback && callback(false)
- return;
- }
- let num = startPercentage + Number(res.speed)
- startPercentage = num > percentage ? percentage : num;
- callback && callback(true)
- }
- },
-
- drawArc(ctx, eAngle, strokeStyle,res) {
- ctx.save();
- ctx.beginPath();
- ctx.lineCap = this.format(res.linecap);
- ctx.lineWidth =Number(res.linewidth);
- ctx.strokeStyle = strokeStyle;
- let radius = res.width / 2;
- let sangle=Number(res.sangle) * Math.PI
- ctx.arc(radius, radius, radius - res.linewidth, sangle, eAngle,this.bool(res.counterclockwise));
- ctx.stroke();
- ctx.closePath();
- ctx.restore();
- }
- }
- }
- </script>
- <script>
- export default {
- name: 'tuiRoundProgress',
- props: {
-
- diam: {
- type: Number,
- default: 60
- },
-
- height: {
- type: Number,
- default: 0
- },
-
- lineWidth: {
- type: Number,
- default: 4
- },
-
- lineCap: {
- type: String,
- default: 'round'
- },
-
- fontSize: {
- type: Number,
- default: 12
- },
-
- fontColor: {
- type: String,
- default: '#C74547'
- },
-
- fontShow: {
- type: Boolean,
- default: true
- },
-
- percentText: {
- type: String,
- default: ''
- },
-
- defaultShow: {
- type: Boolean,
- default: true
- },
-
- defaultColor: {
- type: String,
- default: '#CCC'
- },
-
- progressColor: {
- type: String,
- default: '#C74547'
- },
-
- gradualColor: {
- type: String,
- default: ''
- },
-
- sAngle: {
- type: Number,
- default: -0.5
- },
-
- counterclockwise: {
- type: Boolean,
- default: false
- },
-
- percentage: {
- type: Number,
- default: 0
- },
-
- multiple: {
- type: Number,
- default: 1
- },
-
- speed: {
- type: [Number, String],
- default: 1
- },
-
- activeMode: {
- type: String,
- default: 'backwards'
- }
- },
- watch: {
- percentage(val) {
- this.percent = val;
- }
- },
- mounted() {
- setTimeout(() => {
- this.percent = this.percentage;
- }, 50);
- },
- data() {
- return {
- percent: -1,
- progressCanvasId: this.getCanvasId()
- };
- },
- methods: {
- getCanvasId() {
- return 'tui' + new Date().getTime() + (Math.random() * 100000).toFixed(0);
- },
- change(e) {
-
- this.$emit('change', e);
- },
- end(e) {
-
- this.$emit('end', e);
- }
- }
- };
- </script>
- <style scoped>
- .tui-circular-container {
- position: relative;
- }
- </style>
|