Click trigger with pass X, Y coordinates value - javascript

When we are click in any HTML element we can get X, Y coordinate in our mouse.
Is it possible in jquery or javascript trigger click event with pass X, Y Coordinates value of HTML element and also pass element z-index value.
Only call #block2 not call #block1.
JS
$(document).ready(function(){
$('#block1 div').on('click', function(e)
{
console.log(document.elementFromPoint(e.pageX, e.pageY));
var X = e.pageX;
var Y = e.pageY;
$('#block1').css({'pointer-events':'none'});
$('#block1 div').css({'pointer-events':'none'});
var eobj = new jQuery.Event("click");
obj.pageX = X;
obj.pageY = Y;
$('#time_slice').trigger(obj);
});
});
$('#block2').on('click', function(e){
console.log(document.elementFromPoint(e.pageX, e.pageY));
$('#block1').css({'pointer-events':'auto'});
$('#block1 div').css({'pointer-events':'auto'});
});
Jsfiddle

You can create a MouseEvent and set clientX and clientY values.
Then dispatch that event.
window.addEventListener("click", function (event) {
console.log(`you clicked at ${event.x},${event.y}`);
});
const event = new MouseEvent('click', {
'clientX' : 200,
'clientY' : 500
});
window.dispatchEvent(event);

Related

How to delete snap.svg element on click

How to delete svg when I click on it? I am using the lib snapsvg. I have plunkered my issue.
The use case is as follows : when user clicks on the svg, I create a circle at the position the user clicked, and if the user clicks on a circle that has been created, I want to delete the circle. I have a strange behavior because the circle is moved but not deleted.
(function() {
var s = Snap("#svg");
s.rect(10, 10, 400, 400);
s.click(handleClick);
function handleClick(event) {
var e = event.target;
var dim = e.getBoundingClientRect();
var x = event.clientX - dim.left;
var y = event.clientY - dim.top;
var c = this.circle(x, y, 10);
c.attr({
fill: '#FFF'
})
c.click(function() {
console.log('click circle');
this.remove();
});
}
})();
I managed to find the solution, the element was not moving, actually it was removed but an other was created. To solve my issue I have just added event.stopPropagation(); inside c.click function :
c.click(function(event) {
console.log('click circle');
this.remove();
event.stopPropagation();
});

How to create a resizable rectangle in JavaScript?

What I mean is that the user presses a mouse button at point xy on an HTML canvas and while the mouse button is pressed the rectangle can be resized according to the movement of the cursor with point xy fixed. Like how highlighting works.
This is what I've got so far but it doesn't seem to be working:
canvas.addEventListener('mousedown', function(e){
var rectx = e.clientX;
var recty = e.clientY;
canvas.onmousemove = function(e){
var df = e.clientX;
var fg = e.clientY;
};
context.rect(rectx, recty, df-rectx, fg-recty);
context.stroke();
}, false);
Assuming there are no transforms (scale, translate) on your canvas context.
Basic steps for having a resizable rectangle are as follows:
Create a mousedown listener that sets a flag indicating the use is holding down the mouse button, as well as sets the "anchor," or initial coordinates.
Create a mouseup listener that unsets the flag.
Create a mousemove listener that, if the flag indicates the mouse is down, redraws the canvas with the rectangle's size changed according to mouse coordinates.
An important note is that client coordinates in the event object are relative to the page, not to your canvas element. You will frequently need to convert clientX and clientY into canvas coordinates:
var getCanvasCoords = function (clientX, clientY) {
var rect = canvas.getBoundingClientRect();
return {
x: clientX - rect.left,
y: clientY - rect.top
};
};
The first two steps look something like this:
var anchorX;
var anchorY;
var mouseDown = false;
canvas.addEventListener('mousedown', function (event) {
var coords = getCanvasCoords(event.clientX, event.clientY);
anchorX = coords.x;
anchorY = coords.y;
mouseDown = true;
});
canvas.addEventListener('mouseup', function (event) {
mouseDown = false;
});
And the mousemove handler:
canvas.addEventListener('mousemove', function (event) {
var coords = getCanvasCoords(event.clientX, event.clientY);
var width = coords.x - anchorX;
var height = coords.y - anchorY;
// clear canvas for redrawing
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillRect(anchorX, anchorY, width, height);
});
Don't Render from mouse events!
The given answer is correct but it is not the best way to do this.
The are two reasons. First the mousemove event can fire up to 600+ times a second but the display only refreshes 60 times a second. Rendering from the input event is many time just a waste of CPU time as the results will be overwritten by the next mouse event before it is ever had a chance to be displayed.
The second reason is that dedicating an event listener to a single task makes it hard to add more functionality. You end up adding more and more code to the mousemove event to handle all the types of input, most of which can be ignored because of the high update speed of the mouse.
Mouse listeners
Mouse event listeners do the minimum possible. They just record the mouse state and no more. Also all mouse events return the mouse position. You should not ignore the mouse position for events like mouse down and up
The following function creates a mouse object for a element. The mouse object has the x,y position relative to the to left of the element, and the current button states for 3 buttons it is left to right button1, button2, button3.
Also when the mouse leaves the element and then releases the mouse button the mouse for the element will not see the mouseup event and not know the mouse button is up. To prevent the mouse buttons from getting stuck you turn off the buttons when the mouse leaves the element.
The best mouse listener is to the whole page as it can track mouse events that happen even when the mouse is outside the window/tab (if the window/tab has focus), but that is a little to complex for this answer.
Function to create a mouse for an element
function createMouse(element){
var mouse = {
x : 0,
y : 0,
button1 : false,
button2 : false,
button3 : false,
over : false,
};
function mouseEvent(event){
var bounds = element.getBoundingClientRect();
mouse.x = event.pageX - bounds.left - scrollX;
mouse.y = event.pageY - bounds.top - scrollY;
if(event.type === "mousedown"){
mouse["button"+event.which] = true;
} else if(event.type === "mouseup"){
mouse["button"+event.which] = false;
} else if(event.type === "mouseover"){
mouse.over = true;
} else if(event.type === "mouseout"){
mouse.over = false;
mouse.button1 = false; // turn of buttons to prevent them locking
mouse.button2 = false;
mouse.button3 = false;
}
event.preventDefault(); // stops default mouse behaviour.
}
var events = "mousemove,mousedown,mouseup,mouseout,mouseover".split(',');
events.forEach(eventType => element.addEventListener(eventType,mouseEvent));
mouse.remove = function(){
events.forEach(eventType => element.removeEventListener(eventType, mouseEvent));
}
return mouse;
}
Using the mouse
It is now just a matter of creating a mouse for the element
var canMouse = createMouse(canvas);
And then in your main render loop do the dragging.
var drag = {
x : 0,
y : 0,
x1 : 0,
y1 : 0,
dragging : false,
top : 0,
left : 0,
width : 0,
height : 0,
}
function mainLoop(){
if(canMouse.button1){ // is button down
if(!drag.dragging){ // is dragging
drag.x = canMouse.x;
drag.y = canMouse.y;
drag.dragging = true;
}
drag.x1 = canMouse.x;
drag.y1 = canMouse.y;
drag.top = Math.min(drag.y, drag.y1);
drag.left = Math.min(drag.x, drag.x1);
drag.width = Math.abs(drag.x - drag.x1);
drag.height = Math.abs(drag.y - drag.y1);
}else{
if(drag.dragging){
drag.dragging = false;
}
}
}
Putting it all together
function createMouse(element){
var mouse = {
x : 0,
y : 0,
button1 : false,
button2 : false,
button3 : false,
over : false,
};
function mouseEvent(event){
var bounds = element.getBoundingClientRect();
// NOTE getting the border should not be done like this as
// it will not work in all cases.
var border = Number(element.style.border.split("px")[0])
mouse.x = event.pageX - bounds.left - scrollX - border;
mouse.y = event.pageY - bounds.top - scrollY - border;
if(event.type === "mousedown"){
mouse["button"+event.which] = true;
} else if(event.type === "mouseup"){
mouse["button"+event.which] = false;
} else if(event.type === "mouseover"){
mouse.over = true;
} else if(event.type === "mouseout"){
mouse.over = false;
mouse.button1 = false; // turn of buttons to prevent them locking
mouse.button2 = false;
mouse.button3 = false;
}
event.preventDefault(); // stops default mouse behaviour.
}
var events = "mousemove,mousedown,mouseup,mouseout,mouseover".split(',');
events.forEach(eventType => element.addEventListener(eventType,mouseEvent));
mouse.remove = function(){
events.forEach(eventType => element.removeEventListener(eventType, mouseEvent));
}
return mouse;
}
var drag = {
x : 0,
y : 0,
x1 : 0,
y1 : 0,
dragging : false,
top : 0,
left : 0,
width : 0,
height : 0,
}
var ctx = canvas.getContext("2d");
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
var mouse = createMouse(canvas);
function update(){
ctx.clearRect(0,0,canvas.width,canvas.height);
if(mouse.button1){ // is button down
if(!drag.dragging){ // is dragging
drag.x = mouse.x;
drag.y = mouse.y;
drag.dragging = true;
}
drag.x1 = mouse.x;
drag.y1 = mouse.y;
drag.top = Math.min(drag.y, drag.y1);
drag.left = Math.min(drag.x, drag.x1);
drag.width = Math.abs(drag.x - drag.x1);
drag.height = Math.abs(drag.y - drag.y1);
}else{
if(drag.dragging){
drag.dragging = false;
}
}
if(drag.dragging){
ctx.strokeRect(drag.left, drag.top, drag.width, drag.height);
}
requestAnimationFrame(update);
}
requestAnimationFrame(update);
canvas {
border : 1px solid black;
}
Click drag to draw rectangle.<br>
<canvas id="canvas" width= "512" height = "256"></canvas>

Trigger an event to call a function that's inside of a closure

I'm working on a project based on a nice little sample canvas drawing app someone else on the project downloaded and modified. We need to allow the user to click a button elsewhere on the page (not part of the canvas), and have it run a function that came with the sample app. However, the function is inside of a closure. Since I can't call the function directly (right? the closure prevents this? I don't often work with closures), I thought I'd be able to accomplish this by triggering a mouse event at the location the user would click to accomplish the same thing. It's not working, and I don't know why not.
I posted a greatly simplified version at this fiddle. Simple HTML code:
<div id="canvasDiv"></div>
<div id="buttonDiv">
<button>why can't I send a click to the canvas?</button>
</div>
And the simplified version of the downloaded sample app, plus my attempt to use jQuery's .trigger method to trigger the event:
var WM = {};
WM.drawingApp = function(options) {
"use strict";
var canvas, context,
// Add mouse and touch event listeners to the canvas
createUserEvents = function() {
var getElementPos = function(element) {
// straight-forward stuff removed for brevity's sake
return pos;
};
var press = function(e) {
// Mouse down location
var sizeHotspotStartX, toolIndex,
mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX),
mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY);
var elementPos = getElementPos(document.getElementById(options.canvasElementId || 'canvasDiv'));
mouseX -= elementPos.x;
mouseY -= elementPos.y;
announce(mouseX, mouseY);
};
var announce = function(x,y) { alert('press at: ' + x + ', ' + y); }
// Add mouse event listeners to canvas element
canvas.addEventListener("mousedown", press, false);
},
// Creates a canvas element, etc
init = function() {
// Create the canvas
canvas = document.createElement('canvas');
canvas.setAttribute('width', 100);
canvas.setAttribute('height', 100);
canvas.setAttribute('id', 'canvas');
document.getElementById(options.canvasElementId || 'canvasDiv').appendChild(canvas);
context = canvas.getContext("2d"); // Grab the 2d canvas context
createUserEvents();
};
init();
return {};
};
jQuery(document).ready(function() {
jQuery('#buttonDiv').on('click', 'button', function() {
var down = jQuery.Event("mousedown", {
pageX: 50,
pageY: 50
});
jQuery('#canvasDiv canvas').trigger(down);
});
});
As you can see by running the fiddle, if you click inside the box, you get an alert announcing where you clicked. But if you click the button, you don't get an alert. While writing this question, it occurred to me that maybe jQuery's .trigger method isn't a sufficient way to send the click. Its documentation page specifically says that .trigger "does not perfectly replicate a naturally-occurring event". We're open to solutions that don't involve jQuery.
You can define a variable var press; outside of WM, inside of WM, remove var before press and set press = function() {}. You should then be able to call press(down) at click of button
var press;
press = function(e) {
console.log(e);
// Mouse down location
var sizeHotspotStartX, toolIndex,
mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX),
mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY);
var elementPos = getElementPos(
document.getElementById(options.canvasElementId
|| 'canvasDiv')
);
mouseX -= elementPos.x;
mouseY -= elementPos.y;
announce(mouseX, mouseY);
};
jQuery(document).ready(function() {
jQuery('#buttonDiv').on('click', 'button', function() {
var down = jQuery.Event("mousedown", {
pageX: 50,
pageY: 50
});
press(down); // call `press` at `button` click
//jQuery('#canvasDiv canvas').trigger(down);
});
});
// based on http://www.williammalone.com/projects/html5-canvas-javascript-drawing-app-with-bucket-tool/
var press;
var WM = {};
WM.drawingApp = function(options) {
"use strict";
var canvas, context,
// Add mouse and touch event listeners to the canvas
createUserEvents = function() {
var getElementPos = function(element) {
var parentOffset, pos;
if (!element) {
pos = {
x: 0,
y: 0
};
} else {
pos = {
x: element.offsetLeft,
y: element.offsetTop
};
if (element.offsetParent) {
parentOffset = getElementPos(element.offsetParent);
pos.x += parentOffset.x;
pos.y += parentOffset.y;
}
}
return pos;
};
press = function(e) {
console.log(e)
// Mouse down location
var sizeHotspotStartX, toolIndex,
mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX),
mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY);
var elementPos = getElementPos(document.getElementById(options.canvasElementId || 'canvasDiv'));
mouseX -= elementPos.x;
mouseY -= elementPos.y;
announce(mouseX, mouseY);
};
var announce = function(x,y) { alert('press at: ' + x + ', ' + y); }
// Add mouse event listeners to canvas element
canvas.addEventListener("mousedown", press, false);
},
// Creates a canvas element, loads images, adds events, and draws the canvas for the first time.
init = function() {
// Create the canvas (Neccessary for IE because it doesn't know what a canvas element is)
canvas = document.createElement('canvas');
canvas.setAttribute('width', 100);
canvas.setAttribute('height', 100);
canvas.setAttribute('id', 'canvas');
document.getElementById(options.canvasElementId || 'canvasDiv').appendChild(canvas);
context = canvas.getContext("2d"); // Grab the 2d canvas context
createUserEvents();
};
init();
return {};
};
jQuery(document).ready(function() {
jQuery('#buttonDiv').on('click', 'button', function() {
var down = jQuery.Event("mousedown", {
pageX: 50,
pageY: 50
});
press(down)
//jQuery('#canvasDiv canvas').trigger(down);
});
});
var drawingApp = WM.drawingApp({
canvasElementId: "canvasDiv"
});
#canvasDiv canvas {
border: solid black 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div id="canvasDiv"></div>
<div id="buttonDiv">
<button>why can't I send a click to the canvas?</button>
</div>
jsfiddle https://jsfiddle.net/gkvdha3h/5/

Is it possible to send the x and y coordinates of the mouse's current location with a trigger.('mouseup') event?

I'm trying to make a drawing pad that keeps sending the location of the mouse AND registers a "click" every 1 second. I've tried this, but it doesn't seem to be working -
$( "#canvas" ).mouseover(function() {
setInterval(function(){
var mouseLocation = new jQuery.Event("mouseup");
var x = mouseLocation.pageX ;
var y = mouseLocation.pageY ;
$('#canvas').trigger(mouseLocation);
console.log('Interval function is working');
console.log(mouseLocation.pageX);
},400);
});
the console shows the 'Interval function is working', but it says x is not definted
Click events dont have x and y coordinate.
Do grab x and y coordinate you have to attach mousemove or mouseover event to the element.
$(function(){
var canvas = document.getElementsByTagName("canvas")[0];
var offset = $("canvas").offset();
var a = document.getElementById("a");
canvas.addEventListener("mousemove",function(event){
a.innerText = (event.x - offset.left) + " " + (event.y - offset.top)
})
})
since you want continuous polling of x and y coordinates mousemove is better event to be attached.
fiddle:http://jsfiddle.net/BBnuu/

get position of mouse inside interval to move a div with mouse

I'm trying to move a div with the movement of the mouse cursor, but can't understand how to get the newly updated mouse position within my timeout. Maybe there is a simpler way.
var t;
$(document).ready(function(){
$("body").on("mousedown", ".heading", function (e) {
$("body").data("header_click", true);
if ($("body").data("header_click")) {
var container = $("#dialog");
container.css("position", "absolute");
t = setInterval(function(){
//some way to get mouse position
var pos = container.position();
container.css({
top: "",//set based on mouse position
left: "",//set based on mouse position
});
}, 100);
}else{
document.clearInterval(t);
}
});
});
$("body").on("mousedown", ".heading", function (e) {
$("body").data("header_click", false);
});
The solution found here did not work for me.
You will need to bind to the mouse move event and update a document variable.
var currentMousePos = { x: -1, y: -1 };
$(document).on('mousemove', function(event) {
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
});
Then use those positions relative to the absolute positions of the element you are wanting to drag to calculate and update the elements new position.
$(document).ready(function(){
$("body").on("mousedown", ".heading", function (e) {
$("body").data("header_click", true);
if ($("body").data("header_click")) {
var container = $("#dialog");
container.css("position", "absolute");
var containerPos = container.pos();
var mouseTopOffset = containerPos.top - currentMousePos.y;
var mouseLeftOffset = containerPos.left - currentMousePos.x;
container.css("left", mouseTopOffset +"px");
container.css("top", mouseLeftOffset +"px");
}
}
}
I havent really tested this but in theory should do what you need.

Categories

Resources