微信小程序 纯css画仪表盘

文章来源:CSDN 发布日期:2024-06-07 分类:小程序博客 阅读( )

在这里插入图片描述

刚看到设计稿的时候第一时间想到的就是用canvas来做这个仪表盘,虽然本人的画布用的不是很好但还可以写一写😀。话不多说直接上代码。最后有纯css方法

<!--wxml--><canvas canvas-id="circle" class="circle" >
// jsdata: {    canvasWidth: 285, // 画布宽度    canvasHeight: 285, // 画布高度    value: 60, // 当前得分},  /*   * 绘制仪表盘   */  showCanvasRing() {    var that = this;    var ctx = wx.createCanvasContext("circle");    ctx.clearRect(0, 0, that.data.canvasWidth, that.data.canvasHeight); // 清除画布    var circle_r = that.data.canvasWidth / 2; //画布的一半,用来找中心点和半径    var scoreText = that.data.value>=100?100:that.data.value; // 当前得分 最多100分    var descript = '良好'; // 当前描述    var date = formatTime(new Date(),'MM-DD'); // 当前日期    // 圆弧起点    var startAngle = 0.8 * Math.PI;    var endAngle = 2.2 * Math.PI;    //定义起始点    ctx.translate(that.data.canvasWidth / 2, that.data.canvasHeight / 2);    // 画圆背景    ctx.beginPath();    ctx.setStrokeStyle("#6bb7b9");    ctx.fillStyle="#6bb7b9";    ctx.setLineCap("round");    ctx.arc(0, 0, circle_r,2*Math.PI);    ctx.fill()    ctx.stroke();    ctx.closePath();    //  白半边圆弧    ctx.beginPath();    ctx.setStrokeStyle("#FFFFFF");    ctx.setLineWidth(10);    ctx.setLineCap("round");    ctx.arc(0, 0, circle_r - 20, startAngle, endAngle, false);    ctx.stroke();    ctx.closePath();    // 刻度    for (let i = 0; i <= 10; i++) {      let angle = startAngle + (endAngle - startAngle - 0.1) * (i * 10) / 100;      if (angle > Math.PI * 2) {        angle = angle - Math.PI * 2      }      const point = that.getPoint(0, 0, circle_r - 44, angle);      const PI_3_2 = Math.PI * 1.5;      const PI_1_2 = Math.PI * 0.5;      ctx.save()      ctx.setFillStyle("#fff");      ctx.setFontSize(13);      ctx.translate(point.x, point.y)      const rotateDegrees = angle >= PI_3_2 ? (angle - PI_3_2) : (angle + PI_1_2);      ctx.rotate(rotateDegrees)      ctx.fillText(i * 10, 0, 0)      ctx.restore()    }    // 当前得分内圆弧    ctx.beginPath();    ctx.setStrokeStyle("#FFA64D");    ctx.setLineWidth(10);    ctx.setLineCap("round");    ctx.arc(0, 0, circle_r - 20, startAngle, startAngle + (endAngle - startAngle) * scoreText / 100, false);    ctx.stroke();    ctx.closePath();    // 分数    ctx.setTextAlign("center"); // 字体位置    ctx.setFillStyle("#fff");    ctx.font = "900 50px Arial"    ctx.fillText(scoreText, 0, -20);    // 描述    ctx.setTextAlign("center"); // 字体位置    ctx.font = "400 15px Arial"    ctx.fillText(descript, 0, 15);    // 日期    ctx.setTextAlign("center");    ctx.setLineWidth(8);    ctx.setFontSize(14);    ctx.fillText(date + ' 更新', 0, 35);    // 绘图    ctx.draw();  },  getPoint: function (x, y, r, angle) {    const x1 = x + r * Math.cos(angle);    const y1 = y + r * Math.sin(angle);    return {      x: x1,      y: y1    }  },

到此仪表盘就画完了,最后需求有变动需要再仪表盘上加文本,众所周知canvas小程序中的层级很高。但是官方说可以使用cover-view | cover-image

 <canvas canvas-id="circle" class="circle" > 	<cover-view class="lowScore" wx:if="{{showView}}">      目前信用分过低    </cover-view> </canvas>

经过验证cover-view可以做到在canvas上悬浮,但是不能满足所有需求;
比如要悬浮scroll-view ,总不能把内容全部用画布来写吧 ~ ~。也有人说可以将绘画完成后的canvas转成图片进行显示wx.canvasToTempFilePath。我同样也试过但是会报错:canvasToTempFilePath:fail fail canvas is empty,怎么解决试了好半天,由于项目着急也没用太多时间研究了。所有最后我决定使用最原始的方法来实现。来看代码吧 ↓ ↓

 <!--wxml--><view class="dashboard">  <view class="dashboard-arc">    <view class="dashboard-scale">      <view wx:for="{{[0,10,20,30,40,50,60,70,80,90,100]}}" wx:key="item">{{item}}</view>    </view>    <view class="dashboard-arc-active" style="background: conic-gradient(#FFA64D 0, #FFA64D {{(value*0.75)}}%, transparent 0, transparent);">      <view class="dashboard-arc-active-end" style="transform: translateX(-50%) rotate({{(value/100)*270}}deg);"></view>    </view>  </view>  <view class="dashboard-content">    <view class="dashboard-content-title">{{value}}</view>    <view class="dashboard-content-text">{{state}}</view>    <view class="dashboard-content-desc">{{tool.formatTime(date,'MM-DD')}} 更新</view>  </view>  <view class="lowScore" wx:if="{{showView}}">目前信用分过低</view>...要悬浮的内容</view>
	/* 仪表盘 */	.dashboard {	    width: 750rpx;	    height: 600rpx;	    background: rgba(70, 165, 168, 1);	    box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.1);	    text-align: center;	    position: relative;	}	.dashboard::before{	  content: '';	  width: 570rpx;	  height: 570rpx;	  position: absolute;	  top: 50%;	  left: 50%;	  transform: translate(-50%, -50%);	  background-color: #6bb7b9;	  border-radius: 50%;	}	.dashboard-arc{	  width: 520rpx;	  height: 520rpx;	  position: absolute;	  top: 50%;	  left: 50%;	  transform: translate(-50%, -50%);	  transform: translate(-50%, -50%) rotate(-135deg);	  border-radius: 50%;	  background: conic-gradient(#fff 0, #fff 75%, transparent 0, transparent);	}	.dashboard-arc::before,	.dashboard-arc::after{	  content: "";	  position: absolute;	  width: 20rpx;	  height: 20rpx;	  border-radius: 50%;	  background: #fff;	}	.dashboard-arc::before{	  left: 50%;	  top: 0;	  background-color: #FFA64D;	  transform: translateX(-50%);	}	.dashboard-arc::after{	  left: 0;	  top: 50%;	  transform: translateY(-50%);	}	.dashboard-arc-active{	  position: absolute;	  width: 100%;	  height: 100%;	  border-radius: 50%;	  top: 0;	  left: 0;	}	.dashboard-arc-active-end{	  position: absolute;	  width: 20rpx;	  height:100%;	  top: 0;	  left: 50%;	  z-index: 1;	}	.dashboard-arc-active-end::before{	  content: '';	  width: 20rpx;	  height: 20rpx;	  position: absolute;	  top: 0;	  left: 0;	  background: #FFA64D;	  border-radius: 50%;	}	.dashboard-scale{	  background-color: #6bb7b9;	  width: 480rpx;	  height: 480rpx;	  border-radius: 50%;	  position: relative;	  top: 50%;	  left: 50%;	  z-index: 99;	  font-size: 20rpx;	  transform: translate(-50%, -50%);	  color: #fff;	}	.dashboard-scale>view{	  position: absolute;	  top: 50%;	  height:calc(100% - 10rpx);	  left: 50%;	  transform: translate(-50%,-50%);	}	.dashboard-scale>view:nth-child(2){	  transform:translate(-50%,-50%)rotate(27deg);	}	.dashboard-scale>view:nth-child(3){	  transform:translate(-50%,-50%)rotate(54deg);	}	.dashboard-scale>view:nth-child(4){	  transform:translate(-50%,-50%)rotate(81deg);	}	.dashboard-scale>view:nth-child(5){	  transform:translate(-50%,-50%)rotate(108deg);	}	.dashboard-scale>view:nth-child(6){	  transform:translate(-50%,-50%)rotate(135deg);	}	.dashboard-scale>view:nth-child(7){	  transform:translate(-50%,-50%)rotate(162deg);	}	.dashboard-scale>view:nth-child(8){	  transform:translate(-50%,-50%)rotate(189deg);	}	.dashboard-scale>view:nth-child(9){	  transform:translate(-50%,-50%)rotate(216deg);	}	.dashboard-scale>view:nth-child(10){	  transform:translate(-50%,-50%)rotate(243deg);	}	.dashboard-scale>view:nth-child(11){	  transform:translate(-50%,-50%)rotate(270deg);	}	.dashboard-content{	  position: absolute;	  width: 300rpx;	  height: 300rpx;	  top: 50%;	  left: 50%;	  transform: translate(-50%, -50%);	  color: #fff;	  border-radius: 50%;	  padding: 20rpx;	}	.dashboard-content-title{	  font-size: 115rpx;	  font-weight: 900;	}	.dashboard-content-text{	  font-size: 25rpx;	}	.dashboard-content-desc{	  font-size: 20rpx;	}

以上就是所有代码了,觉得对你有用的话就点个赞吧 !
最后给大家推荐一个在线题库小程序包含了阿里云认证、腾讯云认证、华为云认证、思科认证、锐捷认证、瓴羊认证、红帽认证、软考、IT认证等等
请添加图片描述

最新文章:

二维码