I have an element let's say 10px height and 300px long.
On mouse enter/over I need to get the mouse cursor position relative to the element which I hovered.
For example, I mouseEnter the element in the middle(150px) of its width. I need to get information that it's 150/300 => 50% of this element.
Similar use case to mine we can find on youtube. When we hover over progress bar, the time of video appear above the bar. When we move mouse, the time follows the mouse.
Do you know the way I can count it based on properties inside mouseEvent?
I think what you want is something like this...
const x1 = 500
const x2 = 800
const y1 = 400
const y2 = 700
let resultX = 0, resultY = 0
document.addEventListener('click', (event) => {
if(event.clientX >= x1 && event.clientX <= x2 && event.clientY >= y1 &&
event.clientY <= y2){
resultX = Math.round((event.clientX / x2) * 100)
resultY = Math.round((event.clientY / y2) * 100)
}
});
Related
I am trying to animate a path incrementally on scroll. I am following the techniques outlined here and here. I have my animation areas broken up into segments, and I am using waypoints to activate each segment. once activated (when the top of the segment hits the top of the viewport), the segment listens for the scroll event and then calculates the percentage of line to animate based on this snippet:
var scrollPercentage = rect.top / rect.height;
This seems to work ok, codepen is here. however I need this animation to start prior to the segment reaching the top of the viewport, say when it is 100px from the top. Also I need a way to calculate the percentage when rect.top is between 0 and 100. For some reason when I add a conditional statement it either a. doesn't fire or b. draws the path backwards:
if (rect.top > 0 && rect.top < 100) {
//unsure what how to calulate and trigger before
//top of viewport
//var scrollPercentage = ?;
} else if (rect.top < 0 && rect.bottom > 0) {
var scrollPercentage = rect.top / rect.height;
}
You just need to add an offset to the rect top and bottom values. Then use that value in your comparison.
I've called it prestart.
var prestart = 100;
if ((rect.top - prestart) < 0 && (rect.bottom - prestart) > 0) {
var scrollPercentage = (rect.top - prestart) / rect.height;
}
I am looking to try and do something like this where the content is off the screen and when you move the mouse the browser follows it around. I was thinking it would be similar to this where the edge of the screen animates when the mouse moves.
It looks like in the original example they use JS to change the transform: matrix. On the second link the screen is animated using greensock and the following code to change the CSS:
// Mouse move tilt effect
$(document).mousemove(function(event){
// Detect mouse position
var xPos = (event.clientX/$(window).width())-0.5;
var yPos = (event.clientY/$(window).height())-0.5;
// Tilt the hero container
TweenLite.to($hero, 0.6, {rotationY:5*xPos, rotationX:5*yPos, ease:Power1.easeOut, transformPerspective:900, transformOrigin:"center"});
// Update text on the page with the current mouse position
$(".bottom strong").text(event.pageX + ", " + event.pageY);
});
Is it possible to do something similar to do what I need?
Based on how I understood your intentions basically what you need to do is.
Create a div container which has width and height greater than window size and fill it up with content
Create div container which has width and height equal to window and overflow: hidden and contains the container in 1.
Center container in 1 in 2 with transform: translateX(-25%) translateX(-25%); and transition: transform 1s;
After that
Detected mouse position
Calculate distance from center of window
And based on that add or remove up to 25% to the translateX and translateY value
EDIT:
document.querySelector('body').style.transition = 'transform 1s';
window.addEventListener('mousemove', event => {
const absMaxX = window.innerWidth / 2;
const absMaxY = window.innerHeight / 2;
const maxDistance = Math.sqrt(Math.pow(absMaxX, 2) + Math.pow(absMaxY, 2));
const mouseX = event.clientX;
const mouseY = event.clientY;
const directionX = mouseX - absMaxX >= 0 ? 1 : -1;
const directionY = mouseY - absMaxY >= 0 ? 1 : -1;
const distance = Math.sqrt(Math.pow(mouseX - absMaxX, 2) + Math.pow(mouseY - absMaxY, 2))
const translation = distance / maxDistance * 100;
document.querySelector('body').style.transform =
`translateX(${directionX * translation}px) translateY(${directionY * translation}px)`
});
This question already has answers here:
Mouse cursor doesn't match with canvas
(2 answers)
Closed 6 years ago.
Im trying to get the users mouse X & Y relative to the actual canvas. For some reason canvas.offsetTop and canvas.offsetLeft is not registering the position of the canvas.
The registration of capture is at window top left -> (0, 0) no matter what. It only captures the clientY and clientX when the parts of the canvas are in the size of the canvas relative to (0, 0).
The below html is nested in other divs that have a shared left position of around 200. I have already tried giving the canvas a position:absolute and tried floating it left as suggested in another question.
Everything works as expected if I dont nest the canvas in any divs.
<div id="checkHoldBoarder" style="position:absolute; top:580px; left:0px;">
<div id="checkerHoldStuff" style="width:800px; height:900px;">
<div id="chkBoardBoarder" style="position;absolute; top:10px; left:0px;">
<div id="chkBoardStuff" style="width:600px; height:402px;">
<canvas id='board' width='600px' height='400px' style='position:relitive; left:0px; top:0px;'></canvas>
<div id='status'></div>
</div>
</div>
</div>
</div>
The function that uses clientX and Y
function getMouse(event){
// get clients mouse movement for logic
var cX = event.clientX + sco.canvas.offsetLeft;
var cY = event.clientY + sco.canvas.offsetTop;
// get the status div for returning client mouse movement and the ID of boxes
var status = document.getElementById('status');
// loop through board square array
for(var i = 0; i < board.square.length; i++){
// set square object to small variable
var s = board.square[i];
// logic for each box boundary
if(cX > s.X && cX < s.X + s.W && cY > s.Y && cY <= s.Y + s.H){
// set status div so user can see the board is interactive and not static
status.innerHTML = 'clientX = '+cX+' | clientY = '+cY+' | id:'+s.id;
}
}
}
**Edit for clarification. Im only interested in pure javaScript answers. **
Try this. I added some code to draw a dot where you click, so you can tell it's getting the correct location in relation to the canvas.
https://jsfiddle.net/jhggd8uz/
$( document ).ready(function() {
document.getElementById('board').addEventListener("mousedown", getMouse, false);
});
function getMouse(event){
console.log("Clicked canvas");
var canvas = document.getElementById('board');
var parentOffset = $(this).offset();
var relX = event.pageX - parentOffset.left;
var relY = event.pageY - parentOffset.top;
console.log("relX: ", relX);
var b_context = canvas.getContext("2d");
b_context.beginPath();
b_context.arc(relX, relY, 5 , 0, 2 * Math.PI, true);
b_context.fillStyle = "blue";
b_context.fill();
return;
// get clients mouse movement for logic
var cX = event.clientX + sco.canvas.offsetLeft;
var cY = event.clientY + sco.canvas.offsetTop;
// get the status div for returning client mouse movement and the ID of boxes
var status = document.getElementById('status');
// loop through board square array
for(var i = 0; i < board.square.length; i++){
// set square object to small variable
var s = board.square[i];
// logic for each box boundary
if(cX > s.X && cX < s.X + s.W && cY > s.Y && cY <= s.Y + s.H){
// set status div so user can see the board is interactive and not static
status.innerHTML = 'clientX = '+cX+' | clientY = '+cY+' | id:'+s.id;
}
}
}
Boy it was hard to give this problem a name...
I've been working on this "progress bar" logic, that when ever the user moves
his/her mouse - the indicator (in this case its progress bar) shows how close cursor is to the wanted object.
Basically it's like "hot 'n cold" kind of thing.
Here's the fiddle
...and this is the problem part
relativeDistance = ((maxMouseDistance - distance) / maxDistance);
if ((maxMouseDistance - distance) > maxDistance){
relativeDistance = 1- (((maxMouseDistance) / maxDistance) -1);
}
Since my code and distance measurements are based on trigonometry, it has a small problem: There's actually atleast two points on the screen, where the wanted distances are equal.
Try it and you'll notice what I mean.
Any ideas on how I could get rid of that...It's propably because of the logics, but I just don't see it.
Does this jsFiddle do what you want?
It uses the nearest corner to the mouse rather than the farthest corner. It will show 0% when the mouse is in any corner, and a positive percentage as the mouse approaches the target, even if the target is off-centre.
(function () {
var mX
, mY
, distance
, $distance = $('#distance')
, $element = $('#thetarget')
, maxMouseDistance
, relativeDistance;
var theWidth = $(document).width();
var theHeight = $(document).height();
$("#theWidth").text(theWidth);
$("#theHeight").text(theHeight);
function pythagoras(length, height) {
var length2 = length * length
, height2 = height * height
return Math.sqrt((length2 + height2));
}
/**/
var target = $("#thetarget");
target.css({
cursor: "default"
, border: "1px solid black"
, margin: 0});
var position = target.position(); // top left of target element
var tX = Math.floor(position.left)
var tY = Math.floor(position.top)
$("#targetPosition").text(tX + ":" + tY);
var corners = [
[0, 0]
, [theWidth, 0]
, [theWidth, theHeight]
, [0, theHeight]
]
function distanceToNearestCorner(x, y) {
var cornerX = x < tX ? 0 : theWidth
var cornerY = y < tY ? 0 : theHeight
return pythagoras(cornerX - tX, cornerY - tY)
}
/*Mouse movement tracking*/
$(document).mousemove(function (e) {
/*Get mouse coordinates*/
mX = e.pageX;
mY = e.pageY;
/*calculate distance between mouse and element*/
distance = pythagoras(tX - mX, tY - mY);
maxMouseDistance = distanceToNearestCorner(mX, mY)
relativeDistance = ((maxMouseDistance - distance) / maxMouseDistance);
$distance.text(distance);
var decimals = distance / 100;
var percents = 100 - (distance / 100);
$("#mouse").text(mX + ":" + mY);
//$("#distanceDecimals").text(decimals);
//$("#dFarCorner").text(maxDistance);
$("#md2FarCorner").text(maxMouseDistance);
$("#formula").text("(E to C max / M to C max) / (M to E distance/100)");
$("#theNumber").text(relativeDistance);
$('.fill').width((relativeDistance * 100) + "%");
});
})();
It doesn't update all the fields, but it does update the progress bar.
Original answer
You seem to have plenty of functions in there which are not being called.
Here's one that I have rewritten... but it doesn't get called:
function calculateDistance(elem, mouseX, mouseY) {
var deltaX = elem.offset().left - mouseX;
var deltaY = elem.offset().top - mouseY;
var delta2 = deltaX * deltaX + deltaY * deltaY;
var delta = Math.floor(Math.sqrt(delta2))
return delta
}
var elem = document.getElementById("targetPosition")
var relativeDistance = calculateDistance(elem , mX, mY)
In my implementation, elem is the HTML element that you consider to be the target. My function is an application of Pythagoras' theorem: it returns the square root of the sum of the distance from the target along the x and y axes, giving the length of the shortest line between the mouse and the target.
When I insert this into your jsFiddle, I see 0 appearing in the M2E Distance field when my cursor is just above the "T" of "Target".
Is this what you are looking for?
Your logic is correct. It's called a locus. http://www.bbc.co.uk/schools/gcsebitesize/maths/geometry/locirev1.shtml
i have a simple jQ script:
a set width/height container
a landscape img (can be bigger or
smaller than container)
when a user mouses over the image, it pans
(no click/drag) until it reaches the end
The equation to move the img to the left is this:
-1(relative mouse-position)*(img width)/(container width)
This works fine, but it leaves a space one the mouse reaches the end of the img.
Fiddle
$("figure img").mousemove( function (e) {
var a = $(this).closest("figure"),
b = $(this).width(),
c = a.width(),
d = (e.clientX - a.offset().left);
$(this).css({
left: -1*(d*b/c)
}, 100);
});
can someone help? I want the img to be completely aligned to the right of the container once the mouse reaches the end.
The correct formula is: -1 * (d/c) * (b - c)
Or, more clearly: -1 * (mouseX / figureWidth) * (imgWidth - figureWidth)
(mouseX / figureWidth) represents the percent of the width of the figure that the mouse is positioned at. It will be a number between 0 and 1.
(imgWidth - figureWidth) represents the biggest X value you want to use to position the image at the opposite side.
Multiplying the percent by the total range of movement gives you the movement amount for the current mouse position!
Updated Fiddle
I suggest using more descriptive variable names such as figureWidth, imgWidth, mouseX etc. Not only will it be easier for you to understand, but it will be easier for people to answer.
This should work: http://jsfiddle.net/0zd5t1wf/4/
i just get the limit value for the left propriety of image (the image width - the figure box)
$("figure img").each( function () {
if($(this).width() >= ($(this).height() * 2.5)) {
$(this)
.attr("class", "panorama")
.mousemove( function (e) {
var a = $(this).closest("figure"),
b = $(this).width(),
c = a.width(),
d = (e.clientX - a.offset().left),
newLeft = -1*(d*b/c),
limitValue = parseInt($(this).width()) - parseInt($("figure").width());
if ( newLeft < 0 && (newLeft *-1) < limitValue ){
$(this).css({
left: newLeft
}, 100);
}
$("#hello").html('why');
});
}
});