Passing data between mouse events - javascript

How can one pass events between mousedown and mouseup specifically? In my mousedown event I create a circle and add it to the DOM, in my mouseup I want to animate the circle. I was hoping to do this by referencing the node without attaching an ID, if possible.
Here's a snippet of my code:
// Mouse down
hitArea.addEventListener('mousedown', function(e) {
var el = new createCircle();
mask.appendChild(el);
TweenMax.set(el, {
transformOrigin: '50% 50%',
x: e.clientX - hitDimensions.left,
y: e.clientY - hitDimensions.top
});
});
// Mouse up
hitArea.addEventListener('mouseup', function(e) {
// Reference to el needed
animateCircle(el, e);
});
You can view my in progress code here: http://codepen.io/getreworked/pen/VjzyLL

You can just use closures:
var el;
hitArea.addEventListener('mousedown', function(e) {
el = new createCircle();
mask.appendChild(el);
TweenMax.set(el, {
transformOrigin: '50% 50%',
x: e.clientX - hitDimensions.left,
y: e.clientY - hitDimensions.top
});
});
// Mouse up
hitArea.addEventListener('mouseup', function(e) {
if(el)
animateCircle(el, e);
});

Related

Check mouse click

This code should check the mouse position, and if the mouse clicks show this X and Y positions in the console, but it is ignoring the click event and printing in the console the cordinates of the mouse without the click.
How do I fix this?
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
canvas.addEventListener("click", check(mousePos.x,mousePos.y));
}, false);
function check(x,y){
console.log(x);
}
In this case it would be better to avoid nested eventListeners.
Also you might store the cursor position as a canvas.mouse property:
var canvas = document.querySelector('canvas');
canvas.addEventListener('mousemove', getMousePos);
canvas.addEventListener("click", check);
function getMousePos(evt) {
var rect = canvas.getBoundingClientRect();
canvas.mouse = {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function check() {
console.log(canvas.mouse.x);
}
canvas {
width: 200px;
height: 200px;
background: #ddd
}
<canvas></canvas>
but it is ignoring the click event and printing in console the cordinates of the mouse without the click. How do i fix this?
It's doing that because of the mousemove is firing whenever you move the mouse inside the canvas, and this line :
canvas.addEventListener("click", check(mousePos.x,mousePos.y));
Is calling the check() function that's why it's printing without a click.
as a side note when supplying a call back don't use () because that is invoking the function, and whatever it returns will become the callback, instead you supply the name of the function.
canvas.addEventListener("click", check);
Since you want it to print mouse position on click, You don't necessarily need mousemove, a simple click event is enough
DEMO
var canvas = document.querySelector('canvas');
canvas.addEventListener("click", function(e) {
console.log('X:' + e.clientX, 'Y:' + e.clientY);
});
canvas {
width: 200px;
height: 200px;
background: dodgerblue;
}
<canvas></canvas>

Click trigger with pass X, Y coordinates value

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);

Move multiple divs on the same page

My problem is when I add a mousemove listener on document, all divs are moving but when I add a mousemove listener on my element, I have to move the cursor slowly.
Here is my code :
let componentsItems = document.getElementsByClassName("componentItem");
[].forEach.call(componentsItems, function (componentItem) {
componentItem.addEventListener("click", function (event) {
let selectedComponent = getComponentToDisplay(event.target.getAttribute("data-exchange"));
let mapContainer = document.getElementById("mapContainer");
let mainElement = document.createElement("div");
mainElement.innerHTML = "test";
mainElement.style.position = "absolute";
mapContainer.appendChild(mainElement);
mainElement.addEventListener("mouseup", function (e) {
isDown = false;
});
mainElement.addEventListener("mousedown", function (e) {
isDown = true;
offset = [
mainElement.offsetLeft - e.clientX,
mainElement.offsetTop - e.clientY
];
});
document.addEventListener("mousemove", function (e) {
e.preventDefault();
mousePosition = {
x: e.clientX,
y: e.clientY
};
let left = (mousePosition.x + offset[0]);
let top = (mousePosition.y + offset[1]);
if(isDown){
if(mapContainer.offsetTop < top && mapContainer.offsetWidth > left){
mainElement.style.left = left + 'px';
mainElement.style.top = top + 'px';
}
}
});
});
});
For each component in my menu, I add an onclick listener to appendChild element in the "MapContainer" div.
The drag and drop problem.
The problem is you are attaching multiple mousemove listeners to document, and each one with every one of the different mainElements.
The solution:
Remember which element we are about to move.
mainElement.addEventListener("mousedown", function (e) {
isDown = true;
element = mainElement;
offset = [
mainElement.offsetLeft - e.clientX,
mainElement.offsetTop - e.clientY
];
});
On the outter scope (outside foreach) create a unique mousemove event listener, and update the element that we mousedowned before.
document.addEventListener("mousemove", function (e) {
e.preventDefault();
mousePosition = {
x: e.clientX,
y: e.clientY
};
let left = (mousePosition.x + offset[0]);
let top = (mousePosition.y + offset[1]);
if(isDown){
if(mapContainer.offsetTop < top && mapContainer.offsetWidth > left){
element.style.left = left + 'px';
element.style.top = top + 'px';
}
}
});
Other ways to solve this problem is to create (and delete) the eventlistener on the mousedown and mouseup event handlers respectively. But I believe it's less efficient and definitely more complicated.

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/

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