uni-app中自定义图表(canvas实现chart图表)开发篇(4)-圆环和刻度结合为齿轮进度条

这篇博客介绍了如何通过JavaScript和Vue实现一个齿轮形状的进度条,结合了圆环和时针刻度的元素。在Vue组件中,创建了charts.js文件来绘制图表,通过canvas进行底层开发,实现更灵活的定制。在样式和功能实现中,详细展示了构造函数、绘制方法以及页面交互逻辑,包括进度值的增加和减少。整个过程展示了自定义图形相对于使用插件的优势,即在满足高要求或定制需求时能更高效地完成任务。
摘要由CSDN通过智能技术生成

前面几篇讲了圆环和时针刻度进度条,这篇将会结合这两个图形,绘制出齿轮形状的进度条。在不断积累过程中,我们会发现从底层开发,并不是很困难,更为灵活。所以对于要求高或定制需求,所用时间,会远远小于通过插件修改所消耗的精力。

要实现图形如下:

一、创建对应页面

1.1 创建charts.js文件

/**
 * 图表 - 圆环和刻度结合为齿轮进度条
 */
export class CircleBox {
	//构造函数
	constructor(_context){
	
	}
	
	//绘制图表
	drawCircle(){
		
	}
}

1.2 创建vue页面

<template>
	<view class="wrap-box">
		<view class="echart-box chart01">
			<view class="title">图表:圆环和刻度结合为齿轮进度条</view>
			<view class="content">
				<canvas canvas-id="chartBox4" id="chartBox4" class="chart"></canvas>
				
				<view class="btn-box">
					<button type="default" class="btn" @click="mulEvent()">减小</button>
					<button type="default" class="btn" @click="addEvent">增加</button>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import { CircleBox } from './charts.js';
	export default {
		data() {
			return {
				cbox1: null,       //画布实例对象
				percent: 0,        //当前进度值
				step: .1           //每次修改递增或递减值
			}
		},
		mounted() {
			this.initCircle1();
		},
		methods: {
			mulEvent(){
				//递减
				this.percent = this.percent - this.step <= 0 ? 0 : this.percent - this.step;
				//修改进度值
				this.cbox1.percent = this.percent;
				//开始绘制
				this.cbox1.drawCircle();
			},
			addEvent(){
				//递增
				this.percent = this.percent + this.step >= 1 ? 1 : this.percent + this.step;
				//修改进度值
				this.cbox1.percent = this.percent;
				//开始绘制
				this.cbox1.drawCircle();
			},
			initCircle1(){
				//实例对象
				this.cbox1 = new CircleBox(uni.createCanvasContext('chartBox4'));
				//开始绘制
				this.cbox1.drawCircle();
			}
		}
	}
</script>

<style lang="scss">
@import '../index.scss';
</style>

1.3 scss样式页面

        样式和前两篇一样。

二、实现chart图表

2.1 构造函数中定义变量

//构造函数
constructor(_context){
	this.ctx = _context;
	//刻度数
	this.number = 50;
	//直径
	this.radius = uni.upx2px(300);
	//内填充
	this.padding = uni.upx2px(20);
	//线宽
	this.lineWidth = uni.upx2px(20);
	//刻度宽度
	this.scaleWidth = uni.upx2px(10);
	//刻度高度
	this.scaleHeight = uni.upx2px(8);
	//线颜色
	this.lineColor = "#D7EAFF";
	//占比
	this.percent = 0;
	//百分比颜色
	this.percentColor = "#297DFE";
	//字体大小
	this.fontSize = uni.upx2px(42);
	//字段颜色
	this.fontColor = '#297DFE';
}

2.2 开始绘制

在第三篇中,已经对时针刻度相关计算进行详细解说,不清楚的可以去了解下。

以下代码,是几篇整合而来,基本上都差不多,只有部分细节进行了修改。代码如下:

//绘制图表
drawCircle(){
	//清空画布
	this.ctx.clearRect(0, 0, this.radius, this.radius);
	//计算实际直径(减掉四周内填充)
	let _radius = this.radius/2-this.padding*2;
	
	//开始绘制圆环
	this.ctx.beginPath();
	this.ctx.arc(this.radius/2,this.radius/2, _radius,0,Math.PI*2, false);
	this.ctx.lineWidth = this.lineWidth;
	this.ctx.strokeStyle = this.lineColor;
	this.ctx.stroke();
	
	//计算角度值(倾斜平均值)
	let _depth = Math.PI*2/this.number;			
	//绘制时刻底色
	//计算刻度直径(减去四周内填充)
	let _scaleRadius = this.radius - this.padding * 2;
	
	//开始底色部分绘制
	this.ctx.beginPath();
	this.ctx.strokeStyle = this.lineColor;
	this.ctx.lineCap = 'round';
	//循环绘制刻度
	for(var i=0;i<this.number;i++){
		this.ctx.save();
		this.ctx.lineWidth=this.scaleHeight;
		//把基点设置为圆心
		this.ctx.translate(this.radius/2,this.radius/2);
		this.ctx.rotate(_depth*i);
		this.ctx.moveTo(_scaleRadius/2 ,0);
		this.ctx.lineTo(_scaleRadius/2-this.scaleWidth,0);
		this.ctx.stroke();
		this.ctx.restore();  
	}
	
	//绘制高亮进度条
	this.ctx.beginPath();
	this.ctx.lineCap = 'round';
	this.ctx.arc(this.radius/2,this.radius/2, _radius,-(Math.PI / 2), ((Math.PI * 2) * this.percent) - Math.PI / 2, false);
	this.ctx.strokeStyle = this.percentColor;
	this.ctx.stroke();
	//恢复之前保存的绘图上下文
	this.ctx.restore();
	
	// 绘制高亮刻度
	this.ctx.beginPath();
	this.ctx.strokeStyle = this.percentColor;
	//四舍五入,获取高亮刻度数
	let _highNumber = Math.round(parseFloat(this.number*this.percent).toFixed(2));
	for(var i=0;i<_highNumber;i++){
		this.ctx.save();
		this.ctx.lineWidth= this.scaleHeight;
		//把基点设置为圆心
		this.ctx.translate(this.radius/2,this.radius/2);
		this.ctx.rotate(
			_depth*i-(_depth*Math.round(this.number/4))
		);
		this.ctx.moveTo(_scaleRadius/2 ,0);
		this.ctx.lineTo(_scaleRadius/2-this.scaleWidth,0);
		this.ctx.stroke();
		this.ctx.restore();      
	}
	
	//绘制文字
	this.ctx.font = 'bold '+this.fontSize+'px sans-serif';
	this.ctx.setFillStyle(this.fontColor);
	this.ctx.setTextAlign('center');
	this.ctx.fillText(parseInt(this.percent*100)+'%', this.radius/2+(this.lineWidth/2), this.radius/2+(this.lineWidth/2), this.radius);

	//绘制到画布上
	this.ctx.draw();
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值