I have some problem. I need to calculate some mouse move in pixels from mousedown event to mouseup. So i have this code:
selectArea.on({
mousedown : function(e) {
select = true;
},
mousemove : function(e) {
var x2, y2, offset = $(this).offset();
x2 = e.pageX - offset.left,
y2 = e.pageY - offset.top,
width = ?,
height = ?
...
},
mouseup : function() {
select = false;
}
});
Now i need to know how many pixels i have moved mouse from mousedown offset to mouseup offset, is there any posible to calculate this? Much thx for help.
There are two different solutions, depending on your definition of "how many pixels i have moved"
Scenario: Mouse moves 25px to the right and 75px to the left.
Solution 1: 50px; (distance between start and end)
In the mousedown handler you save the coordinates of the mouse. In the mouseup handler you compute the difference between the current mouse coordinates and the saved ones.
Solution 2: 100px; (distance traveled)
In the mousedown handler you set a boolean to indicate you are recording and save the coordinates of the mouse and initialize the distance with 0. In the mousemove handler you compute the difference between the current mouse coordinates and the saved coordinates (add it to distance) and then you overwrite the saved coordinates with your current mouse coordinates. In the mouseup handler you output the distance and unset the boolean.
You code seems to be for the second solution, but the question asks for the first.
Related
It's more of a question really, but I don't know where to start with this one at all. I'm working on a site at the moment and we've cited the following sites as reference:
http://exhibitions.guggenheim.org/storylines/
http://www.apple.com/uk/start-something-new/
As you can see, both have the same effect and allow you to pan the 'canvas' within the viewport. I've search high and low but can't find any documentation or plugins for such a thing. The closest I found but it still doesn't allow you to pan with mouseMove is this: http://jmpressjs.github.io/jmpress.js/#/home
Like I say though, it's still quite far away from what I'm trying to achieve. Any thoughts, ideas, suggestions or plugins people might know of would be massively appreciated!
Pan canvas with mouse
You can pan the canvas with the ctx.translate(x,y) function, but this function is relative and can be tricky to use if you do not understand matrix math. Or with ctx.setTransform(1,0,0,1,x,y) where the last two numbers set the origin location on the canvas. This function is absolute so you do not need to track the current transformation matrix. The origin is the where coordinates 0,0 are.
Using setTransform
So if you set the the origin to
ctx.setTransform(1,0,0,1,canvas.width/2,canvas.height/2)
and then draw a circle at 0,0
ctx.beginPath();
ctx.arc(0,0,100,0,Math.PI*2);
ctx.fill();
it will appear in the center of the canvas as that is where the new origin is.
Implementing
Now all you need is to use the mouse to pan.
First create var to track the origin location
var originX = 0; // default to the top left of the canvas.
var originY = 0;
Depending on how you render the following will flag when to update the canvas transform
var panOnMouse = true; // if you are using requestAnimationFrame
// or another realtime rendering method this should
// be false
Then create a helper function to set the origin
function setCanvasOrigin(ctx){
ctx.setTransform(1,0,0,1,originX,originY);
}
The mouse
Now the mouse event listener and tracking the mouse movements First a object to hold mouse information.
var mouse = {
x : 0, // holds the current mouse location
y : 0,
lastX : null, // holds the previous mouse location for use when mouse down
lastY : null, // as this is unknown start with null
buttonDown : false, // true if mouse button down;
panButtonID : 1, // the id of the pan button 1 left 2 middle 3 right
}
Then create an event listener to get the mousemove, mousedown, and mouseup
function mouseEvent(event){
if(buttonDown){ // if mouse button is down save the last mouse pos;
mouse.lastX = mouse.x;
mouse.lastY = mouse.y;
}
mouse.x = event.offsetX;
mouse.y = event.offsetY;
if (mouse.x === undefined) { // for browsers that do not support offset
mouse.x = event.clientX;
mouse.y = event.clientY;
}
// now handle the mouse down
if (event.type === "mousedown" && event.which === mouse.panButtonID ) {
mouse.buttonDown = true; // flag the pan button is down;
mouse.lastX = mouse.x; // set the last pos to current
mouse.lastY = mouse.y;
}
// now do the pan is the mouse is down
//
if(mouse.buttonDown){
originX += mouse.x - mouse.lastX; // add the mouse movement to origin
originY += mouse.y - mouse.lastY;
if(panOnMouse ){
setCanvasOrigin(ctx);
}
}
// handle the mouse up only for the pan button
if (event.type === "mouseup" && event.which === mouse.panButtonID) {
mouse.buttonDown = false;
}
}
If you have panOnMouse as false then call setCanvasOrigin at the start of your main render loop.
All that is needed now is to add the mouse event listener to the canvas.
canvas.addEventListener("mousemove",mouseEvent);
canvas.addEventListener("mousedown",mouseEvent);
canvas.addEventListener("mouseup",mouseEvent);
Last notes
So now when the user clicks and drags with the correct mouse button the canvas origin will be dragged to where ever it is wanted. It can even be off screen. Just draw everything as you normally did.
To reset the pan just set the origin to zero
originX = 0; // default to the top left of the canvas.
originY = 0;
setCanvasOrigin(ctx); // set the transform
Because the origin has moved the mouse position on the canvas does not match the panned canvas coordinates. To get the position of the mouse over the panned canvas just subtract the origin from the mouse. You can add it to the end of the mouse event function
mouse.realX = mouse.x - originX; // get the mouse position relative to the
mouse.realY = mouse.y - originY; // panned origin
If the user moves off the canvas while panning you may lose the mouse up event and have the button stuck down. You can listen to mouseout and mouseover events to control what happen in those situations.
And that is how to pan the canvas with the mouse.
I am trying to create a canvas that allows me to draw on it rectangles using mouse events. Very similar to the way selection works in windows, I want to be able to click down anywhere on my page, drag left/right/up/down, then once I release, a rectangle is drawn with the starting coordinates (x1 and y1) on mousedown and the ending coordinates (x2, y2) on mouseup.
I've been trying to create eventListeners bound to my canvas that return the starting and ending coordinates on mousedown and mouseup respectively, but my variables stay undefined.
My canvas spans the entire length of my window so no need to take into account relative positioning. Also the solution has to be implemented using purely Javascript, no JQuery allowed.
Thank you for your help!
UPDATE
Ignore most of what is underneath, re-reading your question, it seems like you have the theory nailed. Your problem is most likely the mousedown and mouseup function parameters are missing. Try the following;
document.getElementsByTagName('canvas')[0].addEventListener('mousedown', function(e){
// I THINK IT'S THE e ON THE LINE ABOVE THIS THAT YOU'RE MISSING.
// YOU CAN THEN ACCESS THE POSITION OF THE MOUSE USING;
mouse.x = e.pageX;
mouse.Y = e.pageY;
})
I won't write the code for you, but I can give you theory.
Store your mouse x & y variables in an object such as mouse = {}.
Add an event listener to the canvas for mouse down (click) and store the e.pageX and e.pageY in mouse.firstX and mouse.firstY. Use something like:
document.getElementsByTagName('canvas')[0].addEventListener('mousedown', function(e){
mouse.firstX = e.pageX;
mouse.firstY = e.pageY;
})
Create a second event listener for the canvas for mouseup and store this set of e.pageX and e.pageY in mouse.secondX and mouse.secondY.
Calculate the difference between firstX and secondX, firstY and secondY to work out big your rectangle sound be.
var width = mouse.firstX + mouse.secondX // rect width
var height = mouse.firstY + mouse.secondY // rect height
Then, using these calculations, draw a rectangle on your canvas using firstX and firstY as the position parameters.
I hope this is relatively clear and helpful for you. If not, this might help;
http://simonsarris.com/blog/140-canvas-moving-selectable-shapes
While my function works on my first monitor like it should on my second monitor all coordinates of event are negative. Like its referent point is still on my primary monitor. Event is triggered on drag and drop from html5.
function endDnD(e) {
var parentOff = $(this).parent().offset();
console.log(e);
console.log(e.pageX, e.pageY, parentOff.left, parentOff.top);
var posX = e.screenX - parentOff.left;
var posY = e.pageY - parentOff.top;
$(this).css('left', posX);
$(this).css('top', posY);
}
I think you need to add this into your equation:
window.screen.availLeft
that returns a 0 value if it's the primary screen (left screen by default) or the width of the primary screen as the starting point of the right screen.
look for information and example here:
https://developer.mozilla.org/en-US/docs/Web/API/Screen/availLeft
Note that while this is information on Mozilla's site it should also work for other popular browsers
To get an X coordinate on the current screen you can use:
e.clientX
instead of e.pageX. That will return a x > 0 value.
I would like to have a function run when the mouse is X distance away from an element.
I assume mousemove event should be moved, but since the element may not always be in the same place I'm not sure how to get the mouse position relative to the element?
Does anyone have an example of something similar?
var mX, mY, distance;
$element = $('#YourElementID');
function calculateDistance(elem, mouseX, mouseY) {
return Math.floor(Math.sqrt(Math.pow(mouseX - (elem.offset().left+(elem.width()/2)), 2) + Math.pow(mouseY - (elem.offset().top+(elem.height()/2)), 2)));
}
$(document).mousemove(function(e) {
mX = e.pageX;
mY = e.pageY;
distance = calculateDistance($element, mX, mY);
// do your stuff with distance
});
You will need to bind to the mousemove event, store the coordinates of your elements corners in a global variable and keep checking at every pixel the mouse moved until the vector between current mouse position and your objects coordinates is of length X. that would then be the moment to trigger your custom event which you bound some function to.
i am unaware of a plugin that already does that, so make sure to post a link to the plugin you write here. :)
I'm getting a strange glitch in my javascript (logic error) i'm not sure if its my maths or the way i have structured my code.
The idea i have is to left click and drag to scroll around a map on a canvas. It works perfectly except, when i mouse down to scroll a second time, the map resets back to its x0y0 offset.
So essentially i can't keep scrolling because as soon as i let go of the mouse and mousedown again its back to the start.
So this is how i did it:
//this is in the init function called on body load
canvas.addEventListener("mousedown", mousePos, false);
//relevant functions
function mousePos(e){
mousex = e.pageX;
mousey = e.pageY;
canvas.addEventListener("mousemove", movePos, false);
}
function movePos(e){
canvas.addEventListener('mouseup',onMouseUp,false);
offset_x = e.pageX - mousex; //pixels to move the map along x
offset_y = e.pageY - mousey; //pixels to move the map along y
}
function onMouseUp(){
// on mouse up stop moving the map
canvas.removeEventListener('mousemove',movePos,false);
}
Any ideas?
You might be using offset_x and offset_y incorrectly in code that is not included here. On mouseup, you should add these values to the total offset of the map, and zero them.
You are adding a mouseup handler every time a mouse is moved - is that what you want? The mouseup handler should be instaled only once in mousePos()