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
}
}
Related
I am using AmCharts and would like to know how to stop the clickGraphItem event propagating to a clickGraph event.
The reason I want to stop it is this:
When I click on a bubble in an XY chart I use Mustache to render a little form under the graph with info contained in the dataContext of the clicked item.
As there are many bubbles on the plot I would like to be able to highlight the selected item on the bubble chart after it is clicked so as to let the user know what point the info is being edited for.
However if the user clicks in empty space on the graph (the clickGraph event on it's own) I want to fire event.chart.validateData(); so that the clicked bubble goes back to original colors.
The problem I am encountering is that when I click on the item I get first the clickGraphItem event firing but that also triggers the clickGraph event.
I have tried to put event.event.stopPropagation() at the end of the "Render Mustache and change fill of bubble" method but this does nothing.
The function I am using to handle both events is below:
function showPointForm(event) {
var ev = event
if (ev.item && ev.item.dataContext.data != undefined) {
var bullet = ev.item.bulletGraphics.node;
bullet.setAttribute("stroke",colors.info);
bullet.setAttribute("fill",colors.warning);
$(document).find('#form-area').html(
Mustache.render($(document).find('#form-template').html(),{
data : ev.item.dataContext.data
})
)
}else{
$(document).find('#form-area').html('')
event.chart.validateData();
}
ev.event.stopPropagation()
}
var chart = AmCharts.makeChart('div',configObject)
chart.addListener("clickGraphItem",showPointForm);
chart.addListener("clickGraph",showPointForm);
The idea here is that if the event is from an item, it will change the fill of the bullet and the stroke, and then render a form with some data prop from the item. If the event does not have an item and data, the rendered form get whiped and the chart is redrawn to original styles.
The stopping of event propagation does nothing here to stop the clickGraph event being fired
Any ideas on what I am doing wrong here?
Thanks
SOLUTION:
It turns out that what I was attempting to achieve isn't supported through the standard AmCharts API. The clickGraph event will not fire in empty space on a bubble/XY chart. Instead I attached an event in to the click event of the .amcharts-plot-area.
function showPointForm(event) {
var ev = event
if (ev.item && ev.item.dataContext.data != undefined) {
$(document).find('.highlight').each(function(){
$(this).attr('class', 'amcharts-graph-bullet');
})
var bullet = ev.item.bulletGraphics.node;
bullet.setAttribute("class",'highlight amcharts-graph-bullet');
$(document).find('#form-area').html(
Mustache.render($(document).find('#form-template').html(),{
data : ev.item.dataContext.data
})
)
}else{
$(document).find('#form-area').html('')
event.chart.validateData();
}
}
function reset(){
$(document).find('#form-area').html('')
timelineChart.validateData();
}
var chart = AmCharts.makeChart('div',configObject)
chart.addListener("clickGraphItem",showPointForm);
$(document).on("click",'.amcharts-plot-area',reset);
So now when I click on a bubble, all bubbles that were previously styled with the highlight class have that class removed. Then the clicked bubble has it added.
When there is a click event in the amcharts-plot-area however, the reset() function is called which removes all the highlighted classes again.
This solves my issue but as stated below the stopping of event propagation is not possible.
There isn't a way to prevent chart event propagation. The chart event name is passed in the type property, so you can use that to determine which flow you want. It's not pretty, but that's all you can do:
function showPointForm(event) {
if (event.type == "clickGraphItem") {
// logic for clickGraphItem only
}
else {
// logic for clickGraph
}
}
You could also set a custom flag inside the chart when the clickGraphItem is fired to indicate that it was just triggered so you know not to perform any additional logic if it was bubbled, for example:
function clickGraphHandler(event) {
if (event.type == "clickGraphItem") {
event.chart.clickGraphItemFired = true;
console.log('clickGraphItem')
} else {
if (event.chart.clickGraphItemFired) {
event.chart.clickGraphItemFired = false;
console.log('clickGraph - bubbled from clickGraphItem');
} else {
console.log('clickGraph - not bubbled from clickGraphItem')
}
}
}
Demo
I have an app which handles a lot of jQuery events, and I need a way to differentiate simple clicks from text selections.
I'd like to disable all click events when I detect a text selection. Is this possible? I've thought of doing it like this:
// User presses mouse button
$(window).on('mousedown', function(){
// User moves mouse while pressing mouse button => selection
this.one('mousemove', function(){
// Disable click listener temporarily
$.fn.click = null;
// User releases mouse button => end of selection
}).on('mouseup', function(){
// Stop mousemove event & restore click listener
this.off('mousemove');
$.fn.click = function(){};
});
});
The code obviously won't work but serves to illustrate my goal. Does anyone know of a good way to achieve this?
Something as simple as setting a flag would work for your example.
var flag = true;
...
if(flag === true)
{
--Click listener enabled code here--
}
else
{
--Click listener disabled code here--
}
All you have to do is determine when to enable or disable the flag.
Just use flag, like this:
var flag = 0;
// User presses mouse button
$(window).on('mousedown', function(){
if (flag == 0) {
// do some if click event enabled
}
// User moves mouse while pressing mouse button => selection
this.one('mousemove', function(){
// Disable click listener temporarily
// $.fn.click = null;
flag=1;
// User releases mouse button => end of selection
}).on('mouseup', function(){
// Stop mousemove event & restore click listener
// this.off('mousemove');
// $.fn.click = function(){};
flag = 0;
});
});
I'm making a webpage for iOS. I would like to perform an action when the user scrolls to the very top of the page via tapping the status bar (a shortcut). I don't want to perform this action when the page is scrolled to the top via using finger swipes.
So far, I have this code, which will wrongfully get triggered in both cases:
Event.observe(
window,
"scroll",
function(event) {
if (window.scrollY <= 0) {
alert("You are at the top of the page, but I don't know how you got here");
}
}
);
Since this code is triggered after tap event, you can set a flag on that tap event which you can check later in this scroll event capture
Event.observe(
window,
"scroll",
function(event) {
if ( !flag )
{
if (window.scrollY <= 0) {
alert("You are at the top of the page, but I don't know how you got here");
}
}
flag = false;
}
);
This flag is set when you tap on that status bar
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
Is there any to make the left arrow behave like the tab button (set focus to the next focusable item) and the right arrow behave like a shift+tab (set focus to the previous focusable item)?
I've gotten this far:
$().keypress(function(e) {
if (e.keyCode == 37) {
alert('I want to do a shift-tab');
}
else if (e.keyCode == 39) {
alert('I want to do a tab');
}
});
But google isn't being that helpful so I thought I'd put a quick post up here while I google some more.
Thanks!
Oh, and it's purely for FF3.0 so I don't need to worry about other browser nuisances.
What you have so far seems fine.
You could keep a list of 'focusable' items and just iterate through the list keeping a pointer to the current one:
// or $('input')..depends what you want to focus on
var nodes = $('.focusable'), idx = -1;
$().keypress( function(e) {
if (e.keyCode === 37) {
nodes.get(++idx).focus();
}
else if (e.keyCode === 39) {
nodes.get(--idx).focus();
}
});
This is just a rough outline though. You'd need to check the idx before doing something to make sure you don't slip past the beginning or end of the focusable elements array. You'll also need to be careful about calling this when the user is inside of a textbox.