Reputation: 66355
Please run the code snippet below - you will see an angled line derived from the corners of a box. Given mouse movement, I would like to move the marker along this line - where either:
So far I haven't got anywhere but I'll update if I do and many thanks for any help.
PS doesn't really matter if it doesn't move exactly along the line - it's the algorithm to move along an angle I'm interested in.
Fiddle: http://jsfiddle.net/ngr3dbhx/3/
var boxEl = document.getElementById('box');
var lineEl = document.getElementById('line');
var markerEl = document.getElementById('marker');
var rad, deg;
// Draw an angled line for demonstration purposes.
function getElementOffset (el) {
var rect = el.getBoundingClientRect();
var docEl = document.documentElement;
var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;
return {
top: rectTop,
left: rectLeft
};
}
function calcAndDrawAngle () {
var boxOffset = getElementOffset(boxEl);
var x1 = boxOffset.left;
var y1 = boxOffset.top;
var x2 = boxOffset.left + boxEl.offsetWidth;
var y2 = boxOffset.top + boxEl.offsetHeight;
var deltaX = x2 - x1;
var deltaY = y2 - y1;
rad = Math.atan2(deltaY, deltaX);
deg = rad * (180 / Math.PI);
lineEl.style.transform = 'rotate(' + deg + 'deg) translate(-50%, 0)';
}
// On mouse move I want to move the marker along the anged line..
// Do something with rad or deg?
document.addEventListener('mousemove', function (e) {
markerEl.style.top = e.clientY + 'px';
markerEl.style.left = e.clientX + 'px';
});
calcAndDrawAngle();
window.addEventListener('resize', calcAndDrawAngle);
html,
body {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#box {
position: absolute;
top: 20%;
left: 30%;
width: 35%;
height: 30%;
border: 1px solid #999;
}
#line {
position: absolute;
top: 0;
left: 0;
transform-origin: top left;
height: 1px;
width: 9999em;
background-color: black;
}
#marker {
position: absolute;
width: 8px;
height: 8px;
background-color: red;
}
<div id="box">
<div id="line"></div>
</div>
<div id="marker"></div>
Upvotes: 1
Views: 159
Reputation: 3363
you mean this?
https://jsfiddle.net/2q1nLh3q/1/
The formula is basic mathematics:
y = k * x + d
Where k
is deltaY / deltaX
and d
is the point where the line crosses the y axis.
So your function could look like this:
document.addEventListener('mousemove', function (e) {
window.requestAnimationFrame(function() {
var boxOffset = getElementOffset(boxEl);
var k = boxEl.offsetHeight / boxEl.offsetWidth;
var d = boxOffset.top - boxOffset.left * k;
var mouseY = k * e.clientX + d;
markerEl.style.top = mouseY + 'px';
markerEl.style.left = e.clientX + 'px';
});
});
Upvotes: 1
Reputation: 46323
Using fairly simple math, calculate y for any x within limited range (subtracted 4 to place rectangle at center):
//var canvas = document.getElementById('canvas');
var boxEl = document.getElementById('box');
var lineEl = document.getElementById('line');
var markerEl = document.getElementById('marker');
var rad, deg;
var coords;
// Draw an angled line for demonstration purposes.
function getElementOffset (el) {
var rect = el.getBoundingClientRect();
var docEl = document.documentElement;
var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;
return {
top: rectTop,
left: rectLeft
};
}
function calcAndDrawAngle () {
var boxOffset = getElementOffset(boxEl);
var x1 = boxOffset.left;
var y1 = boxOffset.top;
var x2 = boxOffset.left + boxEl.offsetWidth;
var y2 = boxOffset.top + boxEl.offsetHeight;
coords = [{x:x1,y:y2},{x:x2,y:y1}];
var deltaX = x2 - x1;
var deltaY = y2 - y1;
rad = Math.atan2(deltaY, deltaX);
deg = rad * (180 / Math.PI);
lineEl.style.transform = 'rotate(' + deg + 'deg) translate(-50%, 0)';
}
// On mouse move I want to move the marker along the anged line..
// Do something with rad or deg?
document.addEventListener('mousemove', function (e) {
var x = Math.min(Math.max(e.clientX, coords[0].x), coords[1].x) - 4;
var y = coords[0].y + ((coords[1].y - coords[0].y) * (coords[1].x - x) / (coords[1].x - coords[0].x));
markerEl.style.top = y + 'px';
markerEl.style.left = x + 'px';
});
calcAndDrawAngle();
window.addEventListener('resize', calcAndDrawAngle);
html,
body {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#box {
position: absolute;
top: 20%;
left: 30%;
width: 35%;
height: 30%;
border: 1px solid #999;
}
#line {
position: absolute;
top: 0;
left: 0;
transform-origin: top left;
height: 1px;
width: 9999em;
background-color: black;
}
#marker {
position: absolute;
width: 8px;
height: 8px;
background-color: red;
}
<div id="box">
<div id="line"></div>
</div>
<div id="marker"></div>
Upvotes: 1