cshenfu
2024-06-27 58aa6e282bb343503be3cb198948328ea3ed7b79
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<template>
    <view class="progress_box">
        <canvas class="progress_bg" canvas-id="cpbg"
            :style="{width:progress_width+'px',height:progress_height+'px'}"></canvas>
        <canvas class="progress_bar" canvas-id="cpbar"
            :style="{width:progress_width+'px',height:progress_height+'px'}"></canvas>
    </view>
</template>
<script>
    /**
     * circleProgress 自己写的环形进度条
     * @property {String Number} value 圆环进度百分比值,为数值类型,0-100(默认必传).
     * @property {String Number} progress_time 圆环进度总时间
     * @property {String Number} border_width 圆环边框宽度
     * @property {String Number} progress_width 圆环宽度(建议宽高一致)
     * @property {String Number} progress_height 圆环高度(建议宽高一致)
     * @property {String Number} radius 圆环半径
     * @property {String} bg_color 圆环的背景色
     * @property {String} start_color 圆环开始渐变色
     * @property {String} bg_color 圆环结束渐变色
     */
    export default {
        props: {
            value: {
                type: Number,
                default: 25,
                required: true
            },
            progress_time: {
                type: Number,
                default: 1200
            },
            progress_width: {
                type: Number,
                default: 250
            },
            progress_height: {
                type: Number,
                default: 250
            },
            border_width: {
                type: Number,
                default: 12
            },
            radius: {
                type: Number,
                default: 100
            },
            bg_color: {
                type: String,
                default: '#FFF7EC'
            },
            start_color: {
                type: String,
                default: '#FF960C'
            },
            end_color: {
                type: String,
                default: '#FF7F36'
            },
        },
        data() {
            return {
                percent: 0, // 保存进度值的变化前后值,用于比较用
            }
        },
        mounted() {
            this.drawProgressbg();
            this.drawCircle(this.value);
        },
        methods: {
            // 背景
            drawProgressbg: function() {
                // 自定义组件实例 this ,表示在这个自定义组件下查找拥有 canvas-id 的 <canvas/>
                let ctx = uni.createCanvasContext('cpbg', this);
                ctx.setLineWidth(this.border_width);
                ctx.setStrokeStyle(this.bg_color);
                ctx.setLineCap('round');
                ctx.beginPath();
                ctx.arc(this.progress_width/2, this.progress_height/2, this.radius, 0.99 * Math.PI, 0.01 * Math.PI, false);
                ctx.stroke();
                ctx.draw();
            },
            // 画圆(递归调用)
            drawCircle: function(step) {
                if (step === 0) return;
                let time = Math.floor(this.progress_time / 100)
                let ctx = uni.createCanvasContext('cpbar', this);
                let gradient = ctx.createLinearGradient(28, 55, 192, 55);
                gradient.addColorStop('0', this.start_color);
                gradient.addColorStop('1.0', this.end_color);
                ctx.setLineWidth(this.border_width);
                ctx.setStrokeStyle(gradient);
                ctx.setLineCap('round');
                ctx.beginPath();
                step = 0.01 * step + 0.99;
                if (step === 1) {
                    step = 0.99
                }
                if (step >= 2) {
                    step = step % 2;
                }
                if (step === 1.99) {
                    step = 0.01
                }
                ctx.arc(this.progress_width/2, this.progress_height/2, this.radius, 0.99 * Math.PI, step * Math.PI, false);
                ctx.stroke();
                ctx.draw();
                if (this.value > this.percent) {
                    this.percent++
                    setTimeout(() => {
                            this.drawCircle(this.percent)
                        },
                        time)
                }
            }
        }
    };
</script>
 
<style>
    .progress_box {
        position: relative;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        text-align: center;
    }
 
    .progress_bg {
        position: absolute;
 
    }
</style>