How to find out the rendered size of a curve in Html5 canvas 2d?

Asked

Viewed 110 times

8

I need to figure out the rendered size of a curve on canvas 2d

context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);

with this code, for example

// pontos de controle
var cp1x = 200,
    cp1y = 150,
    cp2x = 260,
    cp2y = 10;

var x = 0,
    y = 0;

// calculação
var curveWidth = cp1x > x ? cp1x - x : x - cp1x,
    curveHeight = cp1y > y ? cp1y - y : y - cp1y;

However, point cp2 can further lengthen the curve if it exceeds an initial or final point (this is what happens in this code, cp1x = 200, cp2x = 260). For example, let’s assume that the point cp2 is marked with the red dot in this image and that its x coordinate is greater than the x coordinate of cp1, which appears to be the end point of the curve:

ponto cp2

So how can I consider the width of point cp2 in the value of curveWidth and the value of curveHeight to be exact?

1 answer

1

Comrade found your question very interesting, I had never worked with the canvas Ezier and I took a test to play.

I understand from your question that you want to know the distance from the left side to the point of the most right curve, that being the width of the curve.

I wish I could say something like curveWidth = cpx1 + ( (cpx2 - cpx1)/2 ) but in reality it is that in my tests I could not find a mathematical relationship that remained constant, so this relationship changes a lot according to the values of the variables at all times.

But I noticed that in your question you are not seeing in the graph the 2 control points of the Bezier and I believe that it makes all the difference to improve your understanding of how you can find this distance.

Just as a debug tool, I made a code that may help you in this understanding and help you find a suitable answer, follows below:

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	
	<style>
		body { margin:0; padding:0;}
		#dot1 {background-color:red; position:absolute; z-index:999;}
		#dot2 {background-color:blue; position:absolute; z-index:998;}	
		#dot1,#dot2 {width:8px; height:8px;  border-radius: 8px;}
	</style>

	<!-- https://en.wikipedia.org/wiki/B%C3%A9zier_curve -->
</head>
<body>

	<span id="dot1"></span>
	<span id="dot2"></span>
	
	<canvas id="meucanvas" width="500" height="400" style="border:1px solid #d3d3d3;">
	Your browser does not support the HTML5 canvas tag.</canvas>

	<script>
	cp1x = 150;
	cp1y = 25;

	cp2x = 400;
	cp2y = 200;

	x = 300;
	y = 300;

	function cria_grafico(cp1x, cp1y, cp2x, cp2y, x, y)
	{
		var c = document.getElementById("meucanvas");
		var ctx = c.getContext("2d");
		
		ctx.clearRect(0, 0, 500, 400);		
		
			ctx.beginPath();
			ctx.moveTo(0, 0);
			
			ctx.strokeStyle = "#000000";
			ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
			ctx.stroke();
			
			ctx.strokeStyle = "#ff0000";
			ctx.strokeText("cp1 ( "+cp1x+", "+cp1y+" )", cp1x+10, cp1y+10);
			ctx.beginPath();
			ctx.moveTo(0,0);
			ctx.lineTo(cp1x,cp1y);
			ctx.stroke();				

	
			ctx.strokeStyle = "#0000ff";
			ctx.strokeText("cp2 ( "+cp2x+", "+cp2y+" )", cp2x+10, cp2y+10);	
			ctx.beginPath();
			ctx.moveTo(x,y);
			ctx.lineTo(cp2x,cp2y);
			ctx.stroke();				

			
		document.getElementById("dot1").style.left=cp1x+'px';
		document.getElementById("dot1").style.top=cp1y+'px';	
		

		document.getElementById("dot2").style.left=cp2x+'px';
		document.getElementById("dot2").style.top=cp2y+'px';	
	}	
	
	window.onload=function()
	{
	
		document.getElementById("cp1x").value = cp1x;
		document.getElementById("cp1y").value = cp1y;

		document.getElementById("cp2x").value = cp2x;
		document.getElementById("cp2y").value = cp2y;

		document.getElementById("x").value = x;
		document.getElementById("y").value = y;	

		cria_grafico(cp1x, cp1y, cp2x, cp2y, x, y);		
	
	}
	

	function redesenhar()
	{
		cp1x = parseInt( document.getElementById("cp1x").value );
		cp1y = parseInt( document.getElementById("cp1y").value );	

		cp2x = parseInt( document.getElementById("cp2x").value );
		cp2y = parseInt( document.getElementById("cp2y").value );	
		
		x = parseInt( document.getElementById("x").value );
		y = parseInt( document.getElementById("y").value );		

		cria_grafico(cp1x, cp1y, cp2x, cp2y, x, y);		
	}
	</script>	

	
	<br clear="both">
	
	cp1x: <input type="text" id="cp1x">
	cp1y: <input type="text" id="cp1y">

	<br><br>

	cp2x: <input type="text" id="cp2x">
	cp2y: <input type="text" id="cp2y">

	<br><br>
	
	x: <input type="text" id="x">
	y: <input type="text" id="y">	
	
	<input type="button" value="Redesenhar" onclick="redesenhar()">


</body>
</html>

If this answer helps you in anything, give a +1, but do not mark my answer as accepted because I could not answer it. I would like you to publish the answer to your problem when you can solve it.

Good luck and hugs, Anything we exchange ideas here in the question.

  • It seems to be useful! Unfortunately my notebook is not calling, but I will test your code on mobile, vlw by attention

  • 1

    I do not know if in the mobile application appears the button to run the code, but going through the Chrome of my mobile did not appear. Anyway good luck with the design and with the notebook. Suddenly it’s just discharged battery.

  • 1

    I was able to run the code on https://jsfiddle.net, it was just a bit Tricky to copy it :v. Um..., I think the notebook battery is damaged. When I can get back to working on it I will use your utility to see the differences between control points!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.