How to detect mouse x/y in keypress/keydown - javascript

I want to change my cursor image to an animated gif when user press on key.
I tried to change the css "cursor" property but it doesn't move...
So I want to make a div with background image and place it in my cursor X/Y position.
What I tried to do so far is:
var xPlace;
var yPlace;
$(document).mousemove(function(eventParent) {
xPlace = eventParent.pageX;
yPlace = eventParent.pageY;
});
$(document).keydown(function(event) {
if (event.keyCode == 109) {
$("body").addClass("accessibility_cursordetect");
var cursorDetect = '<div class="accessibility_cursordetect_img"></div>';
$(cursorDetect).appendTo("body");
$(".accessibility_cursordetect_img").css({
"top": yPlace,
"right": xPlace
});
}
});
The problem is - in my keydown function -xPlace&yPlace return "undefined"
How can I detect the x/y position of my cursor when the user press on a specific key ("m" for example = keyCode = 109)?
Thank you.

You should be able to use the "cursor" property in the following manner to change the cursor image (using your profile photo in this example) on click of the button considering you already have the jQuery to add the body class:
.accessibility_cursordetect{
cursor: url(https://www.gravatar.com/avatar/9b2dfec811b4643164cba1fd1f244404?s=32&d=identicon&r=PG), auto;
}

Related

without jquery i need to find out if the mouse is over an element, not determine when it becomes over (in case it doesn't move to trigger onmouseover)

without jquery
basically what I am looking for is the ability to see if the mouse is over a div when a countdown finishes
if the user is over the div then perform action for that div
onmouseover only triggers when the mouse crosses the threshold of the div, if the mouse hasn't moved it wouldn't trigger, so that wouldn't work
I need to determine if the mouse is currently over a div at a specific point in time, if it has moved or not from the starting point
all of my hunting has only found onmousover, and nothing to see if the mouse just happens to be there to begin with
I don't have the javascript skills to determine overall coords of div, then map mouse coords and see if it fits there... which is what I believe I need to do
After reading the second answer (the one with millions of a elements) on this SO question, I've came up with this method works without moving the mouse on page load, without involving millions of elements.
HTML
<div id=t></div>
CSS
#t {
/* for illustrative purposes */
width: 10em;
height: 5em;
background-color: #0af;
}
#t:hover {
border-top-style: hidden;
}
JavaScript
document.addEventListener('click', function () {
var c = window.getComputedStyle(document.getElementById('t')).getPropertyValue('border-top-style');
if (c === 'hidden') {
alert('Mouse in box');
} else {
alert('Mouse not in box');
}
}, false);
As stated earlier, bind to the finish event of your countdown instead of the click event on the document.
You may also use any CSS style that's changed on :hover, I chose border-top-style as it is conspicuous. If you're using a border, choose something else.
Here's a jsFiddle.
set a flag to true onmouseover and to false onmouseleave. when countdown finishes if flag is true then it is over element.
HTML
<div id="div-name">the section of the code i am working with has a countdown timer, when it reaches 0 i need to know if the mouse is over a specific box</div>
<button id="notification" onclick="javascript: letsCountIt(5);">click to start countdown</button>
JS
window.ev = false;
document.getElementById('div-name').onmouseover = function () {
window.ev = true;
console.log(window.ev);
}
document.getElementById('div-name').onmouseout = function () {
window.ev = false;
console.log(window.ev);
}
window.letsCountIt = function (cdtimer) {
cdtimer--;
document.getElementById('notification').innerHTML = cdtimer;
if (cdtimer == 0) {
if (window.ev === true) {
alert('over');
} else {
alert('not over');
}
} else {
setTimeout(function(){letsCountIt(cdtimer);}, 1000);
}
}
Look into document.elementFromPoint . When you pass an x,y to elementFromPoint, it will return whatever element (or <body>, if no other specific element) is at that point. You can easily check if this element is the element you want.
The problem then is finding out what point your mouse is at. How to get the mouse position without events (without moving the mouse)? seems to say - don't. At least use mouseMove to track the cursor. The linked question gives examples of how to do so. (Look to the lower scoring answers, as the higher ones only got points for being snarky.)
Just want to say that, I think jQuery's mouseenter and mouseleave events would make this a lot easier, but if you can't use them, maybe this will help you.
Depending on how your page is laid out, this may not be too difficult. You can get the position of your element using the following. Quoting from another answer
element.offsetLeft and element.offsetTop are the pure javascript
properties for finding an element's position with respect to its
offsetParent; being the nearest parent element with a position of
relative or absolute
So, if your element is positioned relatively to the body, so far so good (We don't need to adjust anything).
Now, if we attach an event to the document mousemove event, we can get the current coordinates of the mouse:
document.addEventListener('mousemove', function (e) {
var x = e.clientX;
var y = e.clientY;
}, false);
Now we just need to determine if the mouse falls within the element. To do that we need the height and width of the element. Quoting from another answer
You should use the .offsetWidth and .offsetHeight properties. Note
they belong to the element, not .style.
For example:
var element = document.getElementById('element');
var height = element.offsetHeight;
var width = element.offsetWidth;
Now we have all the information we need, and just need to determine if the mouse falls within the element. We might use something like this:
var onmove = function(e) {
var minX = element.offsetLeft;
var maxX = minX + element.offsetWidth;
var minY = element.offsetTop;
var maxY = minY + element.offsetHeight;
if(e.clientX >= minX && e.clientX <= maxX)
//good horizontally
if(e.clientY >= minY && e.clientY <= maxY)
//good vertically
}
This code works, but the mouse has to be moved once after page load.
var coords;
var getMouseCoordinates = function (e) {
'use strict';
return {
x: e.clientX,
y: e.clientY
};
};
document.addEventListener('mousemove', function (e) {
coords = getMouseCoordinates(e);
}, false);
document.addEventListener('click', function () {
var divCoords = document.getElementById('t').getBoundingClientRect();
if (coords.x >= divCoords.left && coords.x <= divCoords.right && coords.y >= divCoords.top && coords.y <= divCoords.bottom) {
alert('Mouse in box');
} else {
alert('Mouse not in box');
}
}, false);
You wouldn't bind to the click event of document, but rather the finish event of your countdown.
Here's an example. Try clicking in the output window.
You don't need any coordinates or mouse events, if you know a selector for that element:
if (document.querySelector('#elementSelector:hover')) {
alert('I like it when you touch me!');
}

When I click on a canvas and drag my mouse, the cursor changes to a text-selection cursor. How can I prevent this?

Here's a fiddle: http://jsfiddle.net/MZ9Xm/
Note: The following occurs in Chrome 22.0.1221.1, but not in Firefox 14.0.1. [Ubuntu linux]
Move your mouse to the top canvas and press and hold the mouse button. Drag the mouse, and the cursor will change to a text-selection mouse cursor (I-bar). This does not happen if there are no other elements on the page.
I've messed around with setting user-selection to none, but have not had any luck.
You can bind a mousedown event in your canvas to prevent default behavior.
Something like:
// with jQuery
$( "#canvasId" ).mousedown(function(event){
event.preventDefault();
});
// without jQuery
document.getElementById( "canvasId" ).onmousedown = function(event){
event.preventDefault();
};
Here is the updated fiddle: http://jsfiddle.net/MZ9Xm/1/
You will need to test this to see if there is some side effect in what you are doing.
Have you tried using the CSS cursor property ?
canvas {
cursor: pointer;
}
It should display the default cursor.
Try this:
var canvasEls = document.getElementsByTagName('canvas'),
preventHl = function () { return false; },
i = 0;
while (i < canvasEls.length) {
canvasEls[i].onmousedown = preventHl;
i += 1;
}
Returning false will prevent default actions such as highlighting from occurring.

Keep focus on element behind other (z-order) when hovering

I've got an image, and using JQuery I've got it so that the image will increase in size when you hover over it and a DIV that sits under the image will slide up and provide an overlay on the image that is half opacity and occupy the bottom half of the image area.
This works fine, however when you then hover over the overlay (but still on the same area as the image), the image scales down again because you're no longer focused on the image, so the hover out event gets fired.
How do you ignore the overlay when hovering as if to say "I don't care when you hover over the overlay, so long as you're still in the area of the image"?
You could use mousemove event instead of mouseenter and mouseleave and use image dimensions to determine if mouse is over the image.
Example:
$(window).mousemove(function(evt) {
var image = $("#image");
var imageX0 = image.offset().left
var imageY0 = image.offset().top
var imageX1 = imageX0 + image.width()
var imageY1 = imageY0 + image.height()
if( evt.pageX >= imageX0 && evt.pageX <= imageX1 && evt.pageY >= imageY0 && evt.pageY <= imageY1) {
$("#status").text('Hovered!')
} else {
$("#status").text('Not hovered')
}
})
Check out live here: http://dl.dropbox.com/u/486054/stackoverflow/hover-overlay.html

How to use my own button for "next" and "previous" instead button generated on runtime?

This code is adding a span on runtime to change the slide. If I'm on left side of screen it add the span with "previous" and if I'm on right side on the screen it adds span with "next"
(function(){
var scaler=Scaler('bg'),els=$('#bg').children(),width=100/els.length;
var float=$('<span />').css({position:'absolute',color:'#fff',cursor:'pointer',zIndex:2});
var div=$('<div/>').css({position:'absolute',left:0,bottom:0,marginRight:-20,height:'100%'});
div.width(els.css({float:'left',width:width+'%'}).length+'00%').append(els);
var move=function(e){
float[0].style.left=(e=e||window.event).clientX+20+'px';
float[0].style.top=e.clientY+20+'px';
if(float[0].nxt!=(e.clientX>(document.body.offsetWidth/2)))float[0].innerHTML=(float[0].nxt=!float[0].nxt)?'next':'previous'; //Change html only if needed
},
swap=function(e){
var key=e.type=='click'?(e.clientX>(document.body.clientWidth/2)?40:37):e.keyCode;
if(key>36&&key<41)div.animate({left:(scaler(key>38?'+1':'-1').to*-1)+'00%'}); //swap with animation
}
$(window).bind('keydown',swap);
$('#bg').bind('mousemove',move).bind('click',swap).css('cursor','pointer').append(div,float);
/*$('#bg').cycle({ //if using jquery.cycle-plugin the window resizing won't behave too good - fixable
timeout:2000,
after:function(a,b,c){scaler(c.currSlide)}, //but this part is important - scale the current photo
fx:'scrollLeft'
});*/
})();
I want change this behavior. I have my own button in markup called "next" and "previous" which are fixed at left and right side on screen.
<div class="previous">Previous</div>
<div class="next">Next</div>
Can anyone change this code to remove the functionality which add the span on runtime and to give me the facility to use my own Links which are always available on the page.
I added working JS fiddle here
http://jsfiddle.net/jitendravyas/j66Fj/1/
See this change for the jQuery/JavaScript. This works on my browser which is Chrome.
(function(){
var scaler=Scaler('bg'),els=$('#bg').children(),width=100/els.length;
var float=$('<span />').css({position:'absolute',color:'#fff',cursor:'pointer',zIndex:2});
var div=$('<div/>').css({position:'absolute',left:0,bottom:0,marginRight:-20,height:'100%'});
div.width(els.css({float:'left',width:width+'%'}).length+'00%').append(els);
var move=function(e){
float[0].style.left=(e=e||window.event).clientX+20+'px';
float[0].style.top=e.clientY+20+'px';
//if(float[0].nxt!=(e.clientX>(document.body.offsetWidth/2)))float[0].innerHTML=(float[0].nxt=!float[0].nxt)?'next':'previous'; //Change html only if needed
},
swap=function(e){
var key=e.type=='click'?(e.clientX>(document.body.clientWidth/2)?40:37):e.keyCode;
if(key>36&&key<41)div.animate({left:(scaler(key>38?'+1':'-1').to*-1)+'00%'}); //swap with animation
}
$(window).bind('keydown',swap);
$('#bg').css('cursor','pointer').append(div,float);
//bind('mousemove',move).bind('click',swap).css('cursor','pointer').append(div,float);
/*$('#bg').cycle({ //if using jquery.cycle-plugin the window resizing won't behave too good - fixable
timeout:2000,
after:function(a,b,c){scaler(c.currSlide)}, //but this part is important - scale the current photo
fx:'scrollLeft'
});*/
$(".next").click(function(){
$("#bg").trigger(jQuery.Event("keydown", { keyCode: 39 }));
});
$(".previous").click(function(){
$("#bg").trigger(jQuery.Event("keydown", { keyCode: 37 }));
});
})();

Lasso tool in javascript

Hay, I'm writing a simple web based image maker, and would like to know if anyone has any idea's how to implement a lasso tool. I'd like to be able to save all the points so that I can easily send them to a database and retrieve them at a later date.
As a basic plug-in, this would probably look something like this:
$.fn.extend({
lasso: function () {
return this
.mousedown(function (e) {
// left mouse down switches on "capturing mode"
if (e.which === 1 && !$(this).is(".lassoRunning")) {
$(this).addClass("lassoRunning");
$(this).data("lassoPoints", []);
}
})
.mouseup(function (e) {
// left mouse up ends "capturing mode" + triggers "Done" event
if (e.which === 1 && $(this).is(".lassoRunning")) {
$(this).removeClass("lassoRunning");
$(this).trigger("lassoDone", [$(this).data("lassoPoints")]);
}
})
.mousemove(function (e) {
// mouse move captures co-ordinates + triggers "Point" event
if ($(this).hasClass(".lassoRunning")) {
var point = [e.offsetX, e.offsetY];
$(this).data("lassoPoints").push(point);
$(this).trigger("lassoPoint", [point]);
}
});
}
});
later, apply lasso() to any element and handle the events accordingly:
$("#myImg")
.lasso()
.on("lassoDone", function(e, lassoPoints) {
// do something with lassoPoints
})
.bind("lassoPoint", function(e, lassoPoint) {
// do something with lassoPoint
});
lassoPoint will be an array of X,Y co-ordinates. lassoPoints will be an array of lassoPoint.
You should probably include an extra check for a "lasso enabled" flag of some sort into the mousedown handler, so that you can switch it on or off independently.
Heres a plugin that seems to do just that
http://odyniec.net/projects/imgareaselect/examples.html
I haven't used it.
I've never made one, but if you're looking to make your own, id imagine they work like
onmousedown record initial mouse coords(this is the coords of the corner of lasso box)
onmousemove subtract new coords from initial coords to get width and height of div being used for the visual lasso box.
onmouseup, stop listening to mousemove, do something with coords and dimension of any lasso box existing

Categories

Resources