Reputation: 461
In the example fiddle: https://jsfiddle.net/krazyjakee/uazy86m4/ you can drag the mouse around underneath the vector point shown as a blue square. You will see the line draw a path from the vector, through the mouse and to the edge of the viewport where a green square is shown, indicating it has found the edge. However, above the vector, the green square disappears as it fails to detect the edge of the viewport.
Here is the current logic I am using to detect the edge.
const angle = Math.atan2(mouse.y - vectorCenter.y, mouse.x - vectorCenter.x);
const cosAngle = Math.abs(Math.cos(angle));
const sinAngle = Math.abs(Math.sin(angle));
const vx = (viewport.width - vectorCenter.x) * sinAngle;
const vy = (viewport.height - vectorCenter.y) * cosAngle;
const vpMagnitude = vx <= vy ?
(viewport.width - vectorCenter.x) / cosAngle :
(viewport.height - vectorCenter.y) / sinAngle;
const viewportX = vectorCenter.x + Math.cos(angle) * vpMagnitude;
const viewportY = vectorCenter.y + Math.sin(angle) * vpMagnitude;
const viewPortEdge = {
x: viewportX,
y: viewportY,
};
Please help me figure out how to correctly detect the position in the top edge of the viewport.
Upvotes: 0
Views: 57
Reputation: 12677
I didn't look into why exactly this fails for the top because there's an easier approach to this than dealing with angles. You can get the position by some simple vector calculations.
First, for the sake of explicitness and to prevent hardcoding any values into the computation I've extended your viewport
const viewport = {
x: 0,
y: 0,
width: window.innerWidth,
height: window.innerHeight,
get left(){ return this.x },
get right(){ return this.x + this.width },
get top(){ return this.y },
get bottom(){ return this.y + this.height },
};
now the calculation:
//prevent division by 0
const notZero = v => +v || Number.MIN_VALUE;
let vx = mouse.x - vectorCenter.x;
let vy = mouse.y - vectorCenter.y;
//that's why I've extended the viewport, so I don't have to hardcode any values here
//Math.min() to check wich border I hit first, X or Y
let t = Math.min(
((vx<0? viewport.left: viewport.right) - vectorCenter.x) / notZero(vx),
((vy<0? viewport.top: viewport.bottom) - vectorCenter.y) / notZero(vy)
);
const viewPortEdge = {
x: vectorCenter.x + vx * t,
y: vectorCenter.y + vy * t,
};
so t
is the factor by wich I have to scale the vector between the mouse
and the vectorCenter
to hit the closest edge in that particular direction.
Upvotes: 1