canvas使用之beginPath()函数踩坑记

本文介绍了在使用Canvas进行图形绘制时遇到的问题,即使用beginPath()函数来避免线条覆盖,确保根据坐标画出不同颜色的线条。通过分析beginPath()的作用,解释了为何在每次画线前调用该函数以防止颜色混淆,并展示了如何根据条件判断绘制蓝色或黑色线条。同时,文章提到了一个优化问题,即如何避免重复遍历数组来确定画线颜色,并提出了利用标志变量flag的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先贴上网上看到的博客,侵删。

<canvas id="myCanvas" width="300" height="300" style="border:1px solid #000000;">
    您的浏览器不支持 HTML5 canvas 标签。
</canvas>
<script>
    var ctx = document.getElementById("myCanvas").getContext('2d');
    ctx.beginPath();
    ctx.moveTo(100.5,20.5);//①
    ctx.lineTo(200.5,20.5);//②
    ctx.strokeStyle = 'black';//默认strokeStyle='black', lineWidth=1, 此处可省略
    ctx.stroke();

    ctx.moveTo(100.5,40.5);//③
    ctx.lineTo(200.5,40.5)//④
    ctx.strokeStyle = 'red';
    ctx.stroke();
</script>

  • beginPath

canvas中的绘制方法(如stroke, fill),都会以“上一次beginPath”之后的所有路径为基础进行绘制。比如上述代码实际会画两条红线,而不是一条黑线,一条红线,stroke了两次,都是以第一次beginPath后的所有路径为基础画的。

  • 第一次stroke:画①②,黑色

  • 第二次stroke:画①②③④,红色(其中①②红色覆盖之前的黑色)
    不管你用moveTo把画笔移动到哪里,只要不beginPath,那你一直都是在画一条路径(注:此处『一条路径』并非指连在一起)

  • fillRect与strokeRect这种直接画出独立区域的函数,也不会打断当前的path.

我想实现的功能是根据坐标的不同,而画不同颜色的线条,如下图这种形式,之前不知道beginPath的以上特性,所以很困惑画出来的线条始终只有一个颜色,从上面可以看出,只要不beginPath(),那么第二次执行stroke的时候,不管你是否重新写了moveTo(x, y)函数,都会从刚开始的moveTo(x, y)开始画,这样就会覆盖掉之前画的,所以为了解决这个问题,我在每次画线之前都beginPath,然后条件判断,满足相应的条件,就画对应颜色的线,因为每次都beginPath()了,所以不会出现线条覆盖的问题,从而解决这个问题,但是本方法每画一个点,都要beginPath()一次,暂时还没有想到更好的方法。
在这里插入图片描述
主要代码如下,主要逻辑是当m的值在annInt的一奇数下标开头的连续两个整数范围内,就设置画蓝色的线,否则画黑色的线,这里有一个问题是对每一个点m都要遍历数组,来判断它是否应该画蓝色,这里有一个问题是,如何才能知道已经遍历完了整个数组,且m不在范围内,因为可能出现m不在annInt[0]~annInt[1]的范围内,但是在annInt[2]~annINt[3]范围内,于是设置一个标志信息flag,初值为0,每次不满足在数组某两个数范围之间,值就加1.
flag是标志信息,如果当前点m的值并不在annInt的范围内,那么对annInt遍历后,flag的值一定等于(count(annInt))/2,此时可以按正常心电图来画了,当然因为本问题中annInt的length为偶数,一般情况应写成(count(annInt)+1)/2。

	for (; (px / n) < 30000 && m < 90000; px++, m++) {
		
	flag = 0;
		//判断当前坐标点是否处于房颤,房颤用蓝色线条,正常的用黑色线条
	 for(f = 0; f < count(annInt)&&count(annInt) != 0; f+=2){    
		
  
 if(m >= annInt[f] &&  m<annInt[f+1] ){  
	   
			
				ctx.beginPath();
				if(m != 0)
				ctx.moveTo(((px -1)/ n) ,  x_axis - parseFloat(records[m -1]) * 80);
				ctx.strokeStyle = "rgba(0,0,255,1)";
				ctx.lineWidth = 1;
				
				
				ctx.lineTo((px / n ),   x_axis - parseFloat(records[m]) * 80);
				ctx.stroke();
				break;
				
				
			}
 flag++;//flag是标志信息,如果当前点m的值并不在annInt的范围内,那么对annInt遍历后
 //flag的值一定等于(count(annInt))/2,此时可以按正常心电图来画了,当然因为本问题中annInt的length为偶数,一般情况应写成(count(annInt)+1)/2
 if(flag == (count(annInt) )/2 ){
		ctx.beginPath(); //注意啦!
	//if(m != 0)
		ctx.moveTo(((px -1)/ n) ,  x_axis - parseFloat(records[m -1]) * 80);
		
		ctx.strokeStyle = "rgba(0,0,0,1)";
		ctx.lineWidth = 1;
		
		ctx.lineTo((px / n ),   x_axis - parseFloat(records[m ]) * 80);
		ctx.stroke();
		break;
	
	} 

	 }//for(f = 0; f < count(annInt); f++)    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值