Have circle and from it line that targets moving object, need this line to always be fixed length of 30px, so it doesn't reach the moving object, but rather that it only points toward it
I kinda made it as you can see on the second image with canvas.clip(), but isuue is that clip() will remove all other objects from canvas as well.
const canvasMap = document.getElementById("canvasGame");
const cMap = canvasMap.getContext("2d");
// cMap.strokeStyle = "white";
// cMap.beginPath();
// cMap.arc(this.center.x, this.center.y, 30, 0, Math.PI * 2);
// cMap.strokeStyle = "rgba(255, 255, 255, 0)";
// cMap.stroke();
// cMap.clip();
cMap.beginPath();
cMap.moveTo(this.center.x, this.center.y);
cMap.lineTo(this.target.position.x, this.target.position.y);
cMap.strokeStyle = "rgba(255, 255, 255, 1)";
cMap.closePath();
cMap.stroke();
CodePudding user response:
You can calculate the vector from start to end, then normalize it and then multiply it by the length you want.
function lineTowardsPoint(start, end, length) {
// vector form 'start' to 'end'
const dx = end.x - start.x;
const dy = end.y - start.y;
// euclidean distance, length of the vector
const dist = Math.sqrt(dx * dx dy * dy);
// early return if 'start' is closer to the 'end' than 'length'
if (dist<length){
return end;
}
// unit vector form 'start' in direction to 'end', with length 1
const ux = dx / dist;
const uy = dy / dist;
// point with a distance of 'length' from 'start' an the vector to "end"
const x2 = start.x ux * length;
const y2 = start.y uy * length;
return {
x: x2,
y: y2
};
}
const canvasMap = document.getElementById("canvasGame");
const cMap = canvasMap.getContext("2d");
const points = Array(10).fill().map(() => ({
x: Math.random() * 300,
y: Math.random() * 300
}));
const center = {
x: 150,
y: 150
};
cMap.beginPath();
points.forEach(point => {
cMap.moveTo(point.x, point.y);
const target = lineTowardsPoint(point, center, 50);
cMap.lineTo(target.x, target.y);
});
cMap.strokeStyle = "rgba(255, 128, 0, 1)";
cMap.closePath();
cMap.stroke();
#canvasGame {
width: 300px;
height: 300px;
border: 1px solid black;
}
<canvas id="canvasGame" width="300" height="300"></canvas>
CodePudding user response:
Code from Gabriele Petrioli that I edited for my use case
function lineTowardsPoint(start, end, length) {
// vector form 'start' to 'end'
const dx = end.x - start.x;
const dy = end.y - start.y;
// euclidean distance, length of the vector
const dist = Math.sqrt(dx * dx dy * dy);
// early return if 'start' is closer to the 'end' than 'length'
if (dist < length) {
return end;
}
// unit vector form 'start' in direction to 'end', with length 1
const ux = dx / dist;
const uy = dy / dist;
// point with a distance of 'length' from 'start' an the vector to "end"
const x2 = start.x ux * length;
const y2 = start.y uy * length;
return {
x: x2,
y: y2,
};
}
const canvasMap = document.getElementById("canvasGame");
const cMap = canvasMap.getContext("2d");
const point = {
x: this.center.x,
y: this.center.y,
};
const center = {
x: this.target.position.x,
y: this.target.position.y,
};
cMap.beginPath();
// points.forEach((point) => {
cMap.moveTo(point.x, point.y);
const target = lineTowardsPoint(point, center, 50);
cMap.lineTo(target.x, target.y);
// });
cMap.strokeStyle = "rgba(255, 128, 0, 1)";
cMap.closePath();
cMap.stroke();