123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- <template>
- <view class="tm-propressRound d-inline-block">
- <view class="tm-propressRound-text" :style="{
- width:size+'px',
- height:size+'px'
- }">
- <slot name="default" :value="value">
- <text class="text-black" :class="[black?'text-white':'']">{{value}}%</text>
- </slot>
- </view>
- <view class="tm-propressRound-rk">
- <!-- #ifdef MP-WEIXIN || MP-ALIPAY -->
- <canvas :canvas-id="cid" :id="cid"
- :style="{
- width:size+'px',
- height:size+'px'
- }"
- type="2d"
- ></canvas>
- <!-- #endif -->
- <!-- #ifndef MP-WEIXIN || MP-ALIPAY -->
- <canvas :canvas-id="cid" :id="cid"
- :style="{
- width:size+'px',
- height:size+'px'
- }"
- ></canvas>
- <!-- #endif -->
- </view>
- </view>
- </template>
- <script>
- /**
- * 环形进度条
- * @property {Number} value = [] 默认0,推荐使用v-model赋值。value.sync等同。
- * @property {Number} size = [] 默认100,圆环大小。
- * @property {Number} line-width = [] 默认6,圆环线条宽。
- * @property {Array} color = [] 默认['#FF9800','#E91E63','#FF5722'],激活颜色
- * @property {String} bgcolor = [] 默认'#EEEEEE',背景颜色
- * @property {Boolea} semicircle = [] 默认 false,是否半圆
- * @property {Function} input 变化时的值。
- * @property {Function} change 变化时的值。
- * @example <tm-propressRound v-model="checked"></tm-propressRound>
- */
- export default {
- name:"tm-propressRound",
- model:{
- prop:"value",
- event:"input"
- },
- props:{
- black:{
- type:Boolean,
- default:false
- },
- size:{
- type:Number,
- default:100
- },
- lineWidth:{
- type:Number,
- default:10
- },
- value:{
- type:Number,
- default:0
- },
- color:{
- type:Array,
- default:()=>{
- return ['rgb(255,152,0)','rgb(233,30,99)','rgb(255,87,34)']
- }
- },
- bgcolor:{
- type:String,
- default:'rgb(238,238,238)'
- },
- semicircle:{
- type:Boolean|String,
- default:false
- }
- },
- data() {
- return {
- ctx:null,
- timid:null,
- jishu:0,
- cid:'fdd_psd',
- is2d:false
- };
- },
- computed:{
-
- },
- created() {
- // #ifdef H5 || APP-VUE || APP-PLUS
- this.cid = uni.$tm.guid();
- // #endif
- // #ifdef MP-WEIXIN || MP-ALIPAY
- this.is2d=true;
- // #endif
- },
- mounted() {
-
- this.$nextTick(function(){
- this.inits();
- })
- },
- destroyed() {
- clearInterval(this.timid)
- },
- watch:{
-
- value:function(newval,oldval){
- if(newval < 0){
- this.$emit("input",0)
- this.$emit("update:value",0)
- this.$emit("change",0)
- return;
- }else if(newval >100){
- this.$emit("input",100)
- this.$emit("update:value",100)
- this.$emit("change",100)
- return;
- }
- this.$emit("input",newval)
- this.$emit("update:value",newval)
- this.$emit("change",newval)
- let blv = newval - oldval;
- if(newval>=100){
- blv = 100 - oldval;
- }
-
- if(blv >= 0 ){
- this.startHuiZhi(blv,oldval,true)
- }else{
- if(newval<=0){
- blv = oldval;
- }
-
- this.startHuiZhi(Math.abs(blv),oldval,false)
- }
- }
- },
- methods: {
- inits(){
- let t = this;
- if(this.is2d){
- const query = wx.createSelectorQuery().in(this)
- query.select('#'+this.cid)
- .node((res) => {
- const canvas = res.node
- const ctx = canvas.getContext('2d')
- const dpr = uni.getSystemInfoSync().pixelRatio
- canvas.width = res.node._width * dpr
- canvas.height = res.node._height * dpr
- ctx.scale(dpr, dpr)
- t.ctx = ctx;
- t.creatShape();
- this.startHuiZhi(this.value,0,true)
- })
- .exec()
- }else{
- this.ctx = uni.createCanvasContext(this.cid,this)
- this.creatShape();
- this.startHuiZhi(this.value,0,true)
- }
- },
- startHuiZhi(val,oldv,type){
- clearInterval(this.timid);
- let i = 0;
- let t = this;
- // #ifdef H5
- this.timid = setInterval(()=>{
- i += 1;
- if(i>=val){
- clearInterval(t.timid);
- return;
- }
- if(type){
- t.huizhired(oldv+i,type);
- }else{
- t.huizhired(oldv-i,type);
- }
- },5)
- // #endif
- // #ifndef H5
- if(type){
- t.huizhired(val+oldv,type);
- }else{
- t.huizhired(oldv-val,type);
- }
- // #endif
- },
- // 重新绘制。
- creatShape() {
-
- if(!this.ctx) return;
- let ctx= this.ctx;
- let x,y,r ;
- x = y = this.size / 2;
- r = (this.size - this.lineWidth*2) / 2
- if(this.is2d){
- ctx.beginPath()
- ctx.lineCap='round';
- ctx.lineWidth=this.lineWidth-1;
- ctx.strokeStyle=this.bgcolor;
- if(this.semicircle){
- ctx.arc(x, y, r, Math.PI, 0)
- }else{
- ctx.arc(x, y, r, -90, 2 * Math.PI)
- }
- ctx.stroke()
- }else{
- ctx.beginPath()
- ctx.setLineCap('round')
- ctx.setLineWidth(this.lineWidth-1)
- ctx.setStrokeStyle(this.bgcolor)
- if(this.semicircle){
- ctx.arc(x, y, r, Math.PI, 0)
- }else{
- ctx.arc(x, y, r, -90, 2 * Math.PI)
- }
- ctx.stroke()
- ctx.draw(true)
- }
-
-
- },
- huizhired(end=0,type){
- if(!this.ctx) return;
- let ctx = this.ctx;
-
- if(end>=100) end = 100;
- if(end<=0) end = 0;
- let bl = end * 3.6;
-
- bl = bl-90
- let x,y,r ;
- x = y = this.size / 2;
- r = (this.size - this.lineWidth*2) / 2
- if(this.is2d){
-
- ctx.beginPath()
- ctx.lineCap='round';
- ctx.lineWidth=type?this.lineWidth-1:this.lineWidth+1;
- ctx.strokeStyle=this.bgcolor
- if(this.semicircle){
- ctx.arc(x, y, r, Math.PI, 0)
- }else{
- ctx.arc(x, y, r, -90, 2 * Math.PI)
- }
- ctx.stroke()
-
- ctx.beginPath()
- ctx.lineCap='round';
- ctx.lineWidth=this.lineWidth
- var grd=ctx.createLinearGradient(x,0,0,2*x);
- let colorl = this.color.length;
-
- if(colorl==1){
- grd.addColorStop(1,this.color[0]);
- }else if(colorl>1){
- for(let i=0;i<colorl;i++){
- grd.addColorStop(i/(colorl-1),this.color[i]);
- }
- }
- ctx.strokeStyle=grd
-
- if(this.semicircle){
- let val = this.value;
- val = val <=0?0:val;
- val = val>=100?100:val;
- bl = -(Math.PI-this.value/100 * Math.PI)
- ctx.arc(x, y, r, Math.PI, bl)
- }else{
- ctx.arc(x, y, r, -90 * (Math.PI / 180), bl * (Math.PI / 180))
- }
- ctx.stroke()
- }else{
-
- ctx.beginPath()
- ctx.setLineCap('round')
- ctx.setLineWidth(type?this.lineWidth-1:this.lineWidth+1)
- ctx.setStrokeStyle(this.bgcolor)
- if(this.semicircle){
- ctx.arc(x, y, r, Math.PI, 0)
- }else{
- ctx.arc(x, y, r, -90, 2 * Math.PI)
- }
-
- ctx.stroke()
- ctx.draw(true)
-
- ctx.beginPath()
- ctx.setLineCap('round')
- ctx.setLineWidth(this.lineWidth)
- var grd=ctx.createLinearGradient(x,0,0,2*x);
- let colorl = this.color.length;
-
- if(colorl==1){
- grd.addColorStop(1,this.color[0]);
- }else if(colorl>1){
- for(let i=0;i<colorl;i++){
- grd.addColorStop(i/(colorl-1),this.color[i]);
- }
- }
- ctx.setStrokeStyle(grd)
- if(this.semicircle){
- let val = this.value;
- val = val <=0?Math.PI:val;
- val = val>=100?100:val;
- bl = -(Math.PI-this.value/100 * Math.PI)
- bl = Math.abs(bl)>=Math.PI?Math.PI:bl;
- ctx.arc(x, y, r, Math.PI, bl)
- }else{
- ctx.arc(x, y, r, -90 * (Math.PI / 180), bl * (Math.PI / 180))
- }
- ctx.stroke()
- ctx.draw(true)
- }
-
-
-
- },
- },
- }
- </script>
- <style lang="scss" scoped>
- .tm-propressRound{
- position: relative;
- .tm-propressRound-text{
- position: absolute;
- display: flex;
- justify-content: center;
- align-items: center;
- align-content: center;
- }
- }
- </style>
|