yajnab
yajnab

Reputation: 41

Determine the distance between a straight line and a curve line drawn in a HTML canvas

I have a program in HTML, CSS and JavaScript where one can draw a from an initial point (Mousedown event )curved line(Mousemove event) and a straight line when the mouse click is lifted up(MouseUp event).

Now my problem is finding the distance of the curve line and as well as the straight line in two different labels.

My code goes below

var canvas = document.querySelector('#paint');
var ctx = canvas.getContext('2d');

var sketch = document.querySelector('#sketch');
var sketch_style = getComputedStyle(sketch);
canvas.width = parseInt(sketch_style.getPropertyValue('width'));
canvas.height = parseInt(sketch_style.getPropertyValue('height'));

var mouse = {
  x: 0,
  y: 0
};

var last_mouse = {
  x: 0,
  y: 0
};

/* Mouse Capturing Work */
canvas.addEventListener('mousemove', function(e) {
  last_mouse.x = mouse.x;
  last_mouse.y = mouse.y;

  mouse.x = e.pageX - this.offsetLeft;
  mouse.y = e.pageY - this.offsetTop;
}, false);


/* Drawing on Paint App */
ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = 'black';
canvas.addEventListener('mousedown', function(e) {
  initialPoint = {
    x: mouse.x,
    y: mouse.y
  }
  canvas.addEventListener('mousemove', onPaint, false);
}, false);

canvas.addEventListener('mouseup', function() {
  drawStraightLine()
  canvas.removeEventListener('mousemove', onPaint, false);
}, false);

var onPaint = function() {
  ctx.beginPath();
  ctx.moveTo(last_mouse.x, last_mouse.y);
  ctx.lineTo(mouse.x, mouse.y);
  ctx.strokeStyle = "#000000";
  ctx.closePath();
  ctx.stroke();
};

let initialPoint
const drawStraightLine = function() {
  ctx.beginPath();
  ctx.moveTo(initialPoint.x, initialPoint.y);
  ctx.lineTo(mouse.x, mouse.y);
  ctx.strokeStyle = "#FF000077";
  ctx.stroke();
}
html,
body {
  width: 80%;
  height: 50%;
}

#sketch {
  border: 10px solid gray;
  height: 100%;
}
<div id="sketch">
  <canvas id="paint"></canvas>
  <script src="1.js"></script>
</div>
<label id="StraightLineDistance"></label>
<label id="CurvedLineDistance"></label>

Upvotes: 2

Views: 459

Answers (2)

yajnab
yajnab

Reputation: 41

The JavaScript file

const canvas = document.querySelector('#paint');
const ctx = canvas.getContext('2d');

const sketch = document.querySelector('#sketch');
const sketch_style = getComputedStyle(sketch);
canvas.width = parseInt(sketch_style.getPropertyValue('width'));
canvas.height = parseInt(sketch_style.getPropertyValue('height'));
var pathLength = 0;
var distance = 0;

const mouse = {x: 0,  y: 0};
const last_mouse = {x: 0,  y: 0};
const initialPoint  = {x: 0,  y: 0};

function distanceBetween(A, B) {
const dx = B.x - A.x; 
const dy = B.y - A.y; 
return (dx * dx + dy * dy) ** 0.5;
}


/* Drawing on Paint App */
ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = 'black';
canvas.addEventListener('mousedown', function(e) {
initialPoint.x = mouse.x = e.pageX - this.offsetLeft;
initialPoint.y = mouse.y = e.pageY - this.offsetTop;
pathLength = 0;
canvas.addEventListener('mousemove', onPaint);
}, false);

canvas.addEventListener('mouseup', function() {
drawStraightLine()
canvas.removeEventListener('mousemove', onPaint);
}, false);

function displayLengths() {
StraightLineDistance.textContent = "Distance: " + distance.toFixed(0) + "px";
CurvedLineDistance.textContent = "Traveled: " + pathLength.toFixed(0) + "px";

} 

function onPaint(e) {
last_mouse.x = mouse.x;
last_mouse.y = mouse.y;

mouse.x = e.pageX - this.offsetLeft;
mouse.y = e.pageY - this.offsetTop;

ctx.strokeStyle = "#000000";
ctx.beginPath();
ctx.lineTo(last_mouse.x, last_mouse.y);
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();

pathLength += distanceBetween(last_mouse, mouse);
distance = distanceBetween(initialPoint, mouse);
displayLengths();
};


function drawStraightLine() {
ctx.strokeStyle = "#FF000077";
ctx.beginPath();
ctx.lineTo(initialPoint.x, initialPoint.y);
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();

distance = distanceBetween(initialPoint, mouse);
displayLengths();  
}

The HTML file

<link rel="stylesheet" href="1.css"/>
</head>

<body>
<div id="sketch">
<canvas id="paint"></canvas>
<script src="1.js"></script>
</div>
<label id="StraightLineDistance"></label><br/>
<label id="CurvedLineDistance"></label><br/>
<label id="Index"></label>
</body>
</html>

My new doubt is how can I show the realtime value of ratio of (distance/pathLength) in the label id="Index"

I have tried using Index.textContent = (distance/pathLength).toFixed(0); but that shows 1 and its constant in the output. I would be pleased if I am helped with this

Upvotes: 0

Blindman67
Blindman67

Reputation: 54129

To find the length of a line you use Pythagoras

Eg the distance between two points A, B

function distanceBetween(A, B) {
    return ((B.x - A.x) ** 2 + (B.y - A.y) ** 2) ** 0.5;
}

Or

function distanceBetween(A, B) {
    const dx = B.x - A.x; 
    const dy = B.y - A.y; 
    return Math.sqrt(dx * dx + dy * dy);
}

Or

function distanceBetween(A, B) {
    return Math.hypot(B.x - A.x, B.y - A.y);
}

To measure the drawn path you will need to accumulate the length each sub path (line) to get a total.

Example

The example accumulates the length as it is drawn. When the mouse down event happens the accumulated length is zeroed.

const canvas = document.querySelector('#paint');
const ctx = canvas.getContext('2d');

const sketch = document.querySelector('#sketch');
const sketch_style = getComputedStyle(sketch);
canvas.width = parseInt(sketch_style.getPropertyValue('width'));
canvas.height = parseInt(sketch_style.getPropertyValue('height'));
var pathLength = 0;
var distance = 0;

const mouse = {x: 0,  y: 0};
const last_mouse = {x: 0,  y: 0};
const initialPoint  = {x: 0,  y: 0};

function distanceBetween(A, B) {
    const dx = B.x - A.x; 
    const dy = B.y - A.y; 
    return (dx * dx + dy * dy) ** 0.5;
}


/* Drawing on Paint App */
ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = 'black';
canvas.addEventListener('mousedown', function(e) {
  initialPoint.x = mouse.x = e.pageX - this.offsetLeft;
  initialPoint.y = mouse.y = e.pageY - this.offsetTop;
  pathLength = 0;
  canvas.addEventListener('mousemove', onPaint);
}, false);

canvas.addEventListener('mouseup', function() {
  drawStraightLine()
  canvas.removeEventListener('mousemove', onPaint);
}, false);

function displayLengths() {
    StraightLineDistance.textContent = "Distance: " + distance.toFixed(0) + "px";
    CurvedLineDistance.textContent = "Traveled: " + pathLength.toFixed(0) + "px";

}

function onPaint(e) {
  last_mouse.x = mouse.x;
  last_mouse.y = mouse.y;

  mouse.x = e.pageX - this.offsetLeft;
  mouse.y = e.pageY - this.offsetTop;

  ctx.strokeStyle = "#000000";
  ctx.beginPath();
  ctx.lineTo(last_mouse.x, last_mouse.y);
  ctx.lineTo(mouse.x, mouse.y);
  ctx.stroke();

  pathLength += distanceBetween(last_mouse, mouse);
  distance = distanceBetween(initialPoint, mouse);
  displayLengths();
};


function drawStraightLine() {
  ctx.strokeStyle = "#FF000077";
  ctx.beginPath();
  ctx.lineTo(initialPoint.x, initialPoint.y);
  ctx.lineTo(mouse.x, mouse.y);
  ctx.stroke();

  distance = distanceBetween(initialPoint, mouse);
  displayLengths();
}
html,
body {
  width: 80%;
  height: 50%;
}

#sketch {
  border: 10px solid gray;
  height: 100%;
}
<div id="sketch">
  <canvas id="paint"></canvas>
  <script src="1.js"></script>
</div>
<label id="StraightLineDistance"></label>
<label id="CurvedLineDistance"></label>

Upvotes: 0

Related Questions