uniapp canvas游标卡尺效果

本文介绍如何在uniapp中使用canvas实现游标卡尺效果,包括卡尺绘制、游标绘制、左右拉取和移动取值的详细步骤。通过设置不同参数和计算,确保在uniapp中正确显示并实现功能。同时分享了项目的gitee地址和关键代码片段。

效果

根据公司业务仿照写的效果。原项目从微信小程序转uniapp,未测试该效果在android端效果。

uniapp直接使用canvas不可做子组件,否则无效果显示,其次显示时要考虑页面渲染超时的问题。

如效果所见,可以设置取值精度。

gitee地址:project_practice: 项目练习 - Gitee.com

一 卡尺绘制

从最小值到最大值每隔10个绘制,并设置底部数字。

要左右拉取,游标在中间位置。所以在游标不动的情况下,开始绘制位置和{x:0,y:0}距离半个屏幕宽度,绘制结束位置之后也应该保留半个屏幕位置。

假设屏幕宽度为screenWidth,canvas宽度为canvasWidth,最小值为minvaule,最大值为maxvalue,每次绘制距离间隔为ratio。

canvasWidth = (maxvalue-minvaule)*ratio+screenWidth

开始绘制点为origion={x:0,y:0},开始绘制点x坐标值公式:origion.x = screenWidth/2

每次绘制间隔数量interval,越小绘制越密,越大绘制越粗。

代码如下:

function dodrawruler(){
	var context = uni.createCanvasContext(getvalue('canvasid'))
	let minvalue = getvalue('minvalue')
	let maxvalue = getvalue('maxvalue')
	let interval = getvalue('interval')
	
	let origionX = 0
	let len = (maxvalue - minvalue)*ratio
	origionX = screenWidth/2
	let origion = {x:origionX,y:0}
	let i = minvalue

	while(i <= maxvalue){		
		context.beginPath()
		let movetoX=origion.x + (i - minvalue) * ratio
		let movetoY=0
		context.moveTo(movetoX, movetoY);
		let linetoX  = origion.x + (i - minvalue) * ratio
		let linetoY = (i % ratio == 0 ? heightDecimal : heightDigit)
		context.lineTo(linetoX ,linetoY )
		context.setLineWidth(lineWidth2)
		context.setStrokeStyle(i % ratio == 0 ? rulecolor1 : rulecolor2)
		context.stroke()
		context.setFillStyle('gray') 
		if (i % ratio == 0) {
			context.setFontSize(fontSize);
			context.fillText(i == 0 ? ' ' + i : i, origion.x + (i - minvalue) * ratio - fontSize / 2, heightDecimal + 5 + fontSize)
		}
		context.closePath()
		i+=interval
	}
	setTimeout(()=>{// uni-app必须加上延迟,不然显示不出来, 亲测
	  context.draw() 
	}, 20)
}

最后context.draw()必须加setTimout,否则渲染不全。但是小程序不用。

最后context.draw()是while循环结束后一次性绘制。

之所以不用for,是控制变量i的增加数值方便些。

二 游标绘制

先画一个倒等腰三角再画一个竖线,竖线的起始位置,是倒三角向下的顶点。

游标在屏幕中间显示,所以倒三角向下的顶点应该在屏幕中间。

根据公式_a{2}+_b{2} = _c{2},假设边长的一半为harfline,向下的顶点为center:{x:0,y:0}。

center.x = screenWidth/2

center.y = harfline*Math.sqrt(3)

其余两点

right ={x:center.x-harfline,y:0}
left ={x:center.x+harfline,y:0}

三 左右拉取

左右拉取效果用scroll-view组件实现。

scroll-view包裹卡尺canvas,超出屏幕宽度可向左拉取。初始化时应显示canvas中间位置。

假设初始移动位置为scroll_left,scroll_left=canvasWidth/2-screenWidth/2

游标canvas在scroll-view外层,两者的父节点为一个view。

设置canvas样式pointer-events:none;不影响scroll-view鼠标事件,设置样式z-index: 100;控制效果展示。

两层div重叠的css效果原理,父节点设置position: relative;,子节点设置position: absolute;

代码如下

<style scoped>
.showdiv{
	position: relative;
	width: 100%;
}
.showdiv #canvas_ruler{
	position: absolute;
	top: 0;
	left: 0;
	z-index: 0;
}
.showdiv #canvas-cursor{
	position: absolute;
	top: 0;
	left: 0;
	z-index: 100;
	pointer-events:none;
}
</style>
<view class="showdiv" id="showdiv" :style="{height:style.canvasHeight}">
		
        <scroll-view style="width:100%;height: 100%;" 
		:scroll-x="true"  @scroll="scroll" :scroll-left="scroll_left" 
        :show-scrollbar="false">

			<canvas :style="{width:style.canvasWidth,height:style.canvasHeight}" 
			canvas-id="canvas_ruler" id="canvas_ruler" :width="canvasWidth">
			</canvas>

		</scroll-view>

		<canvas :style="{width:style.screenWidth,height:style.canvasHeight}"
		canvas-id="canvas-cursor" id="canvas-cursor">
		</canvas>
</view>

四 移动取值

按照移动距离获取对应游标卡尺对应值。卡尺最左端移动到最小值,最右端移动到最大值。

移动到最小值时,移动距离为0。移动到中间值时,移动距离为canvasWidth/2-screenWidth/2。

实际上screenWidth/2是绘制开始位置,即scroll-view移动距离为0,对应最小值。所以scroll-view移动距离除以ratio,就是游标对应位置的值。但是为从0开始的值,需要加上最小值为正确值。

假设移动时应取值为value,取值精度为precision。

function setcursorvalue(scrollLeft){
	let minvalue = getvalue('minvalue')
	let precision = getvalue('precision')
	let value = 0
	if(precision==0){
		value = Math.round(scrollLeft/10)+minvalue;
	}else{
		value = parseFloat((scrollLeft/10).toFixed(precision))+minvalue
	}
	return value 
}

若项目有问题,请留言。我尽量及时改正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsswear

感谢大佬打赏 q(≧▽≦q)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值