This is for an HTML5 canvas game that I am making. In the game, there is a character that has a gun, he can shoot it and reload it. I would like the player to use the left mouse button for shooting and the right mouse button for reloading.
What I need is that when ever I click the left mouse button, a variable in my player object(Player1.isLeftClick) becomes true, and when I let go of the button the same variable becomes false. The same thing should also happen with the right mouse button, but with another variable(Player1.isRightClick). I also want it to be capable with all the most popular browsers(Chrome, Firefox, Explorer, etc.). I must also be in pure JavaScript with no libraries like jQuery!
I already achieved this with keyboard events, but I need this with the mouse events.
If it helps, I already have event handlers for keyboard up and down and mouse movement. These are made in the init function that initializes the game when the images are loaded.
document.addEventListener('mousemove', mousePos, false);
document.addEventListener('keydown', checkKeyDown, false);
document.addEventListener('keyup', checkKeyUp, false);
I also have variable called mie that is true if the used browser is Internet Explorer and false for other browsers.
You want to use the e.button property to check which mouse event was called. The value for the left mouse button being clicked is different in IE. Your code would look like this:
var left, right;
left = mie ? 1 : 0;
right = 2;
document.body.addEventListener('mousedown', function (e){
if(e.button === left){
Player1.isLeftClick = true;
}
else if(e.button === right){
Player1.isRightClick = true;
}
}, false);
document.body.addEventListener('mouseup', function (e){
if(e.button === left){
Player1.isLeftClick = false;
}
else if(e.button === right){
Player1.isRightClick = false;
}
}, false);
Demo
Related
Is there any way to distinguish a click event that keeps it distinct from when the user actually ends up dragging the mouse? I have some text that is filled with links, and want it to be easy for the user to click and drag over the text to select some of the text, but the links make this difficult, as the browser interprets it as them trying to drag the link, rather than select some text. So my solution to this problem was to use an <a onClick=...> rather than <a href>, as the browser lets me drag the mouse over that just like normal text.
However, this only seems to work if I single click and drag the mouse over two separate <a> tags: if the selection is entirely internal to an <a> tag the event still fires, and if I try to double-click-drag over text it also fires.
So I'm wondering if there's a way to do this other than using onMouseDown and onMouseUp and manually keeping track of the delays to determine what the user is doing.
I'm aware that some browsers offer the option to drag through links by holding a modifier key, but I'm curious if there's a simpler way to do this that wouldn't require users to be aware of that functionality.
Opinion piece
Whilst this might be doable, consider accessibility and how it'll fit into your projects needs. Navigation using onclick doesn't provide the same accessibility benefits, plus it requires a lot of reinventing things the browser can do for free.
I know that mobile devices typically allow a long press to access a text-select/context menu combo; on desktop, it'll vary per device/browser.
Actual answer
The only "detect click only" implementation I can think of would be using three handlers with mousedown, mouseup and mousemove. Untested code ahead!
let clicked = false;
document.addEventListener('mousedown', e => { clicked = true; });
document.addEventListener('mousemove', e => { clicked = false; });
document.addEventListener('mouseup', e => {
if(clicked) {
// The mouse was clicked without moving it around!
// Do your "only clicked" logic in here.
}
// Reset this back to false for next time
clicked = false;
});
Thanks to #Connor Deckers for idea and for this site
let clicked = false;
let dbclicked = false;
let move = false;
document.addEventListener('mousedown', e => { clicked = true; });
document.addEventListener('mousemove', e => { move = true; });
document.addEventListener('dblclick', e => { dbclicked = true; });
document.addEventListener('mouseup', e => {
if(clicked && !move && !dbclicked) {
// The mouse was clicked without moving it around!
// Do your "only clicked" logic in here.
console.log("clicked without drag and not a double click ");
}
if(dbclicked) {
// The mouse was double clicked
// Do your "double clicked" logic in here.
//console.log("dbclicked");
}
// Reset this back to false for next time
clicked = false;
move = false;
dbclicked = false;
});
I'm making a minesweeper clone, left click reveals the cell and right click is supposed to flag the cell.
I'm using the function mouseClicked() - this allows me to reveal on left click and also reveal on right click.
I tried using
if(mouseIsPressed) {
if(mouseButton === LEFT) {
reveal
}
if(mouseButton === RIGHT) {
flag
}
}
This registers once every frame that the button is held down. I just want a single right click. I imagine there is something simple that I'm missing, but I really can't find anything in the documentation or anyone asking about it online.
TL;DR - I just want to be able to right click in p5.js.
The mouseClicked() event only occurs once when the mouse button is pressed.
Set a state flag when the event occurs:
var rightPressed = false;
function mouseClicked() {
if(mouseButton === RIGHT) {
rightPressed = true;
}
}
Reset the flag when the action which is triggered by the event was handled:
function draw() {
if (rightPressed) {
rightPressed = false
// do somthing
// ...
}
}
Use the mouseClicked() function and pass the event.
Then using event.button you can determine if it is a right click like so:
function mouseClicked(event){
if(event.button === 2){
// Right click
}
}
I don't know whether it is only Chrome problem (can't check now), however let's try the following piece of code, where we bind two events to some element:
$("div").on({
mousemove: function(e) {
console.log("move");
},
click: function(e) {
console.log("click");
}
});
If we try to click the element, we'll find that for some reason mousemove event fires immediately after click, so in console we have:
>> ...
>> click
>> move
DEMO: http://jsfiddle.net/gKqVt/
Note, that mousedown and mouseup events work by the same scenario.
I saw many questions on SO about the same problem, but none (in my search) gave the straightforward idea what to do in order to fire the click event only.
Mousemove appears to be binded to every mouse action there is in Chrome, so store the mouse position every time the mouse "moves" and check it against the previous mouse position to validate that it has indeed "moved"..
var currentPos=[];
$("div").on({
mousemove: function(e) {
if (e.pageX!==currentPos[0] && e.pageY !==currentPos[1]){
currentPos=[e.pageX,e.pageY];
this.innerHTML = "Event: " + e.type;
console.log("move");
}
},
click: function(e) {
this.innerHTML = "Event: " + e.type;
console.log("click");
}
});
Demo | Source
This appears to be a bug in Chrome that was first reported back in November, and remains open.
Chromium Issue 161464
If you are targeting Chrome specifically then it may be worth comparing the event timestamps to get around it (using some minimum delta time as #ExplosionPills suggested. But if you're looking for general behavior it seems that you're better off treating them as separate events, because in every browser but chrome (and maybe Safari? the bug is labeled as webkit-core) they will in fact be separate events.
This behavior is odd, and it doesn't seem to occur universally (happens in Chrome/IE for me, but not FFX). I think you haven't gotten a straight answer because there isn't one really.
It's possible that the mouse is moved very slightly by the click action, but that's probably not it. Could just be a browser quirk. These don't even seem to be the same event since stopImmediatePropagation in click doesn't stop mousemove from firing. If you focus the element and hit a keyboard button, it will actually trigger click and only click.
Since this is so quirky, it seems like the only way to deal with it is times. As much of a kludge as this is, I do notice that click happens one millisecond before mousemove, so you could get close by comparing the click timestamp + 2 (or 10):
mousemove: function(e) {
if ($(this).data('lastClick') + 10 < e.timeStamp) {
http://jsfiddle.net/gKqVt/3/
This is very specific, though. You should consider not having behavior that occurs immediately on mousemove since it's so frequent.
Why don't just check that did the mouse really move or not like below:
function onMouseDown (e) {
mouseDown = { x: e.clientX, y: e.clientY };
console.log("click");
}
function onMouseMove (e) {
//To check that did mouse really move or not
if ( e.clientX !== mouseDown.x || e.clientY !== mouseDown.y) {
console.log("move");
}
}
FIDDLE DEMO
(I think it's will still correct in all browsers)
var a,b,c,d;
$(".prd img").on({
mousedown: function(e){
a= e.clientX, b= e.clientY;
},
mouseup: function(e){
c= e.clientX, d= e.clientY;
if(a==c&&b==d){
console.log('clicked');
}
}
});
Try this. This one work correct.
I noticed this behavior when I needed to differenciate between mousedown and mouseup without dragging between the two and mousedown and mouseup with dragging between them, the solution that I used is as follows:
var div = $('#clickablediv');
var mouseDown = false;
var isDragging = 0;
div.mousedown(function () {
isDragging = false;
mouseDown = true;
}).mousemove(function () {
if (mouseDown) isDragging++;
}).mouseup(function () {
mouseDown = false;
var wasDragging = isDragging;
isDragging = 0;
if (!wasDragging || wasDragging<=1) {
console.log('there was no dragging');
}
});
when I tried it, I noticed that periodacaly a simple click makes "isDragging" equal to 3 but not very frequently
I added the following to my mouseMove(event) function:
function mouseMove(event)
{
if ((event.movementX == 0) && (event.movementY == 0)) return;
Not clear why it triggers when there is no movement, but this worked for me. Had the issue in Chrome 102.0.5005.61 at least. It did not happen a few years ago.
So I have my controls set up as space bar to jump but I want my HTML5 game to work everywhere so I need to change it to mouse/touch. Mouse/touch doesnt have a keycode so whats the most optimal way to do it for this code? Do I need to do mouse and touch separately?
if (KEY_STATUS.space && player.dy === 0 && !player.isJumping) {
player.isJumping = true;
player.dy = player.jumpDy;
jumpCounter = 12;
assetLoader.sounds.jump.play();
}
// jump higher if the space bar is continually pressed
if (KEY_STATUS.space && jumpCounter) {
player.dy = player.jumpDy;
}
You are talking about touch events in JavaScript. You will have to add an event listener and catch if the user touches screen. Here you can find a well documented tutorial in how to use it on both touchscreen and mouse.
Check out the first answer, you will have to do it like that. You will have to add an event listener on the canvas itself, like the guy did it on myDiv.
Here is an example I wrote (don't mind me being weird, please):
<div id="fakeCanvas">
Click or touch me!
</div>
<script type="text/javascript">
var fakeCanvas = document.getElementById('fakeCanvas');
function methodToInvokeForClick() {
alert('I have been clicked!');
}
function methodToInvokeForTouch() {
alert('I have been touched!');
}
fakeCanvas.addEventListener("click", methodToInvokeForClick, false);
fakeCanvas.addEventListener("touchstart", methodToInvokeForTouch, false);
</script>
I think you can take it over from now. What I did to the fakeCanvas div, you will have to do the same to your canvas by giving it an id etc. Good luck!
I'm having issues handeling some drag events... What I'm working on is a draggable control panel, and I want to disable click events during the drag. Is there a way to globally disable click events during the drag? Another issue I've found is that when someone starts the drag over a link or image the you get a psuedo-element drag of the image/link and then the control panel is stuck to the mouse because the original drag event got eat up somewhere.
any help or direction would be nice.
this is what i'm working with
dragElement.mousedown(function(event) {
sticker.css('cursor', 'move');
if ((event.button == 1 && window.event != null) || event.button == 0) {
//second catch here in case user stops drag and re-initiates drag
//without moving away from sticker
document.onselectstart = function() {
return false;
};
startDrag(event);
}
});
$(document).mousemove(function(event) {
handleDrag(event);
});
dragElement.mouseup(function() {
endDrag();
$(document).unbind('mousemove', handleDrag);
});
To the link or image elements, try to prevent their default behavior by original JavaScript
event.preventDefault(); //standard browser
or
event.returnValue=true; //IE
or just a function in jQuery for both
event.preventDefault();