vue,uniapp使用canvas绘制会员中心成长值、用户等级。可封装组件使用

仅供参考,可以自己封组件使用

<template>
	<view class="list3">
		<view style="width: 750rpx; height: 350rpx;background-size: cover;background-image: url('https://bpic.588ku.com/ad_diversion/22/09/01/ee5f14ee42db43bed2211537b48a5efd.png!/fw/320/unsharp/true/compress/true') ; " id="scream"></view>
		<canvas style="width: 750rpx; height: 350rpx;" canvas-id="circle" id="circle"></canvas>
	</view>
</template>

<script>
	export default {
		data(){
			return {
				canvas:{
					
				},
				data:[//界面所显示的等级
					'V1','V2','V3','V4','V5','V6','V7','V8','V9',
				],
				progress: 54.45,//进度条
				progressValue: 'V6',//进度所属等级,该字段为空时progress有效
				progressNum:25, // 二级进度:若为100,则表示进入{{progressValue}} 的下一等级,若为50则代表{{progressValue}}和下一等级之间
				tips1:'我的成长值', //界面展示的文字
				tips2:'9800',//界面展示的文字
				tips3:'还差50积分升级v2'//界面展示的文字
			}
		},
		mounted() {
			uni.createSelectorQuery().in(this).select("#circle").boundingClientRect(data => {
						  this.canvas.height = data.height;
						  this.canvas.width = data.width;
						}).exec();
		 this.toCanvas();
		},
		
		methods:{
			toCanvas(id) {
				if(this.progressValue){
					let index = this.data.indexOf(this.progressValue);
					this.progress = index/(this.data.length-1)*100;
					if(this.progressNum){
						this.progress+= this.progressNum/(this.data.length-1)
					}
					console.log(index,this.progress)
				}
				if(this.progress>100){
					this.progress =100;
				}
			     var ctx = uni.createCanvasContext("circle")
			       var percent = this.progress; //最终百分比
			       var circleX =  this.canvas.width/ 2; //中心x坐标
			       var circleY = 170;//this.canvas.height*1.9 / 2; //中心y坐标
			       var radius = 130; //圆环半径
			       var lineWidth = 7; //圆形线条的宽度
			       //中间的字
			       var fontSize = 25;
			       ctx.font = fontSize + "px April";
			       ctx.textAlign = "center";
			       ctx.fillStyle = "#000";
			       ctx.fillText(this.tips2, circleX, circleY*0.7);
			       fontSize = 12;
			       ctx.font = fontSize + "px April";
			       ctx.fillStyle = "#999";
			       ctx.fillText(this.tips1, circleX, circleY*0.7 - 30);
			       ctx.fillStyle = "#999";
			       ctx.fillText(this.tips3, circleX, circleY*0.7 + 20);
			       //画圆
			       function circle(cx, cy, r) {
			         ctx.beginPath();
					  ctx.lineCap = "round";
			         // ctx.moveTo(cx + r, cy);
			         ctx.lineWidth = lineWidth;
			         ctx.strokeStyle = "#848b8c";
			         ctx.arc(cx, cy, r, (Math.PI * 3.3) / 3, (Math.PI * 5.7) / 3);
			         ctx.stroke();
			       }
			       // 画弧线
			       function sector(cx, cy, r, startAngle, endAngle) {
			         ctx.beginPath();
			         //ctx.moveTo(cx, cy + r); // 从圆形底部开始画
			         ctx.lineWidth = lineWidth;
			         // // 渐变色 - 可自定义
			         var linGrad = ctx.createLinearGradient(
			           circleX - radius - lineWidth,
			           circleY,
			           circleX + radius + lineWidth,
			           circleY
			         );
			         linGrad.addColorStop(0.0, "#06a8f3");
			         linGrad.addColorStop(0.1, '#9bc4eb');
			         linGrad.addColorStop(1.0, "#00f8bb");
			          ctx.strokeStyle = linGrad;
			     	
			     				
			         //圆弧两端的样式
			         ctx.lineCap = "round";
			         //圆弧
			         ctx.arc(
			           cx,
			           cy,
			           r,
			           (Math.PI * 3.3) / 3,
			           (Math.PI * 3.3) / 3 + (endAngle / 100) * ((Math.PI * 0.8) ),
			           false
			         );
			         ctx.stroke();
			       }
			      //画等级
				  function dengji(cx,cy,data){
					   ctx.beginPath();
					   var my_gradient=ctx.createLinearGradient(0,0,170,0);
					   my_gradient.addColorStop(0,"#00d8f9");
					   my_gradient.addColorStop(1,"#ffd764");
					   ctx.fillStyle=my_gradient;
					   console.log(cx,cy)
					   for(let i=0;i<data.length;i++){
						   var itemAngle = 250-(157/data.length)*i;
						   var x = cx + radius*1.1 * Math.sin(itemAngle * 3.14 / 180);
						    var y =cy + radius*1.1 * Math.cos(itemAngle * 3.14 / 180);
						    ctx.fillText(data[i],x,y);
					   }
					   ctx.stroke();
				  }
				   dengji(circleX, circleY, this.data)
				   // 圆形
			       circle(circleX, circleY, radius);
			       //圆弧
			       sector(circleX, circleY, radius,(Math.PI * 3.3) / 3, percent);
			       ctx.draw()
			     
			    }
				
		}
	}
	
</script>

<style>
 #canvas{ position: absolute;z-index: 1; }
    #scream{ position: absolute; }
    .list3{float: right; position:relative; }

</style>

部分内容参考了网上的,自己按自己的需求做了修改和优化

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值