Trigger mousemove event using Jquery or Javascript - javascript

Hi I know we can trigger click event . but I want to know that can we trigger mousemove event without any actual mouse movement by user.
Description :
I want to show a message when user select something. on canvas ,my canvas is of full height and width,when user click on a button the canvas shows up. when user do mouse movement he see a message "Click and drag on any part of the web page". this message follows the mouse movement of the user.
What I want to do :
When user click the button he should see the message that "Click and drag on any part of the web page". and message must follow wherever user moves the mouse.
Problem :
User is not able to see the message after click until he/she moves his mouse.
Code:
function activateCanvas() {
var documentWidth = jQ(document).width(),
documentHeight = jQ(document).height();
jQ('body').prepend('<canvas id="uxa-canvas-container" width="' + documentWidth + '" height="' + documentHeight + '" ></canvas><form method="post" id="uxa-annotations-container"></form>');
canvas = new UXAFeedback.Canvas('uxa-canvas-container', {
containerClass: 'uxa-canvas-container',
selection: false,
defaultCursor: 'crosshair'
});
jQ(function() {
var canvas = jQ('.upper-canvas').get(0);
var ctx = canvas.getContext('2d');
var x,y;
var tooltipDraw = function(e) {
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
var str = 'Click and drag on any part of the webpage.';
ctx.fillStyle = '#ddd';
ctx.fillRect(x + 10, y - 60, 500, 40);
ctx.fillStyle = 'rgb(12, 106, 185)';
ctx.font = 'bold 24px verdana';
ctx.fillText(str, x + 20, y - 30, 480);
};
canvas.addEventListener('onfocus',tooltipDraw,0);
canvas.addEventListener('mousemove',tooltipDraw,0);
canvas.addEventListener('mousedown', function() {
canvas.removeEventListener('mousemove', tooltipDraw, false);
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
}, false);
});
}
jQ('body').on('click', '.mood_img_div', function() {
// alert("soemthing");
toggleOverlay();
activateCanvas();
});
I have made a function which is called after click but the message is not visible. Is there any way to call it for the first time with message and show is everytime when user uses mouse.
I have replaced jQuery with jQ because I am making my own plugin(this is not causing the problem)

A good native approach is to use dispatchEvent method on EventTarget.
It dispatches an Event at the specified EventTarget, invoking the affected EventListeners in the appropriate order. The normal event processing rules (including the capturing and optional bubbling phase) also apply to events dispatched manually with dispatchEvent().
Try
// 1. Add an event listener first
canvas.addEventListener('mousemove', tooltipDraw ,0);
// 2. Trigger this event wherever you wish
canvas.dispatchEvent(new Event('mousemove'));
in your case it should trigger mousemove event on canvas element.
(Triggering events in vanilla JavaScript article can be also useful):
var elem = document.getElementById('elementId');
elem.addEventListenter('mousemove', function() {
// Mousemove event callback
}, 0);
var event = new Event('mousemove'); // (*)
elem.dispatchEvent(event);
// Line (*) is equivalent to:
var event = new Event(
'mousemove',
{ bubbles: false, cancelable: false });
jQuery:
Try this with jQuery trigger method:
$('body').bind('mousemove',function(e){
// Mousemove event triggered!
});
$(function(){
$('body').trigger('mousemove');
});
OR (if you need triggering with coords)
event = $.Event('mousemove');
// coordinates
event.pageX = 100;
event.pageY = 100;
// trigger event
$(document).trigger(event);
OR
Try using .mousemove() jQuery method

let coordX = 0; // Moving from the left side of the screen
let coordY = window.innerHeight / 2; // Moving in the center
function move() {
// Move step = 20 pixels
coordX += 20;
// Create new mouse event
let ev = new MouseEvent("mousemove", {
view: window,
bubbles: true,
cancelable: true,
clientX: coordX,
clientY: coordY
});
// Send event
document.querySelector('Put your element here!').dispatchEvent(ev);
// If the current position of the fake "mouse" is less than the width of the screen - let's move
if (coordX < window.innerWidth) {
setTimeout(() => {
move();
}, 10);
}
}
// Starting to move
move();

Albeit it is probably possible to mimic such an event as shown in Andrii Verbytskyi's answer, most of the time, when you want to do it, it is because of an "X-Y problem".
If we take OP's case for instance, here we absolutely don't need to trigger this mousemove event.
Pseudo-code of current implementation :
function mousemoveHandler(evt){
do_something_with(evt.pageX, e.pageY);
}
element.addEventListener('mousemove', mousemoveHandler)
function clickHandler(evt){
do_something_else();
}
element.addEventListener('click', clickHandler);
And what we want is to also call do_something_with in the click handler.
So OP spends some time to find a way to trigger a fake mousemove, spends another amount of time trying to implement it, while all that is needed is to add a call to do_something_with in clickHandler.
Both mousemove and click events have these pageX and pageY properties, so the event can be passed has is, but in other case, we could also just want to pass it with a fake object containing required properties.
function mousemoveHandler(evt){
do_something_with(evt.pageX, evt.pageY);
}
element.addEventListener('mousemove', mousemoveHandler)
function clickHandler(evt){
do_something_else();
do_something_with(evt.pageX, evt.pageY);
}
element.addEventListener('click', clickHandler);
// here we won't have pageX nor pageY properties
function keydownHandler(evt){
do_something_else();
// create a fake object, which doesn't need to be an Event
var fake_evt = {pageX: someValue, pageY: someValue};
do_something_with(fake_evt.pageX, fake_evt.pageY);
}
element.addEventListener('keydown', keydownHandler);
Note : you are mixing jQuery.on and element.addEventListener, so you might need to pass the originalEvent property of the jQuery event object.

Related

How to convert screen coordinates to scene coordinates

I created a a-scene with some objects to drag. The final purpose is exactly what aframe-click-drag-component does. Unfortunately, this component is not compatible with the last version of A-Frame.
I created a custom component.
AFRAME.registerComponent('draggable', {
init: function () {
/* Some code */
}
});
I use the aframe-mouse-cursor-component to be able to get the mouseenter and mouseleave events on the draggable object, and detect when the mouse position allows the user to select the object.
I added an EventListener on document.body to know when the dragging starts:
document.body.addEventListener('mousedown', function (e) {
// start dragging
});
I continuously update a global variable to update the mouse position when a mousemove occurs:
document.addEventListener('DOMContentLoaded', function () {
document.body.addEventListener('mousemove', function (e) {
window.mouseX = e.clientX;
window.mouseY = e.clientY;
});
});
This way, I can easily get the position of the mouse during the dragging. But I do not know how to convert the position of the mouse on the client to a position in the Virtual Reality (restricted to a 2D plan to make it possible).
I solved this issue by using the raycaster coming from the cursor in the middle of the a-camera, but I want to drag the objects with the mouse-cursor, and this component does not have a raycaster.
I also tried to use some maths to convert the mouse coordinates to a coordinates set relative to the camera, without success (essentially because of the screen size which can vary).
What solutions are available? I would like to update the click-drag or the mouse-cursor, but I have no knowledge of THREE.js.
See https://github.com/mayognaise/aframe-mouse-cursor-component or https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/DragControls.js or https://www.npmjs.com/package/aframe-click-drag-component for examples
The main chunk of code is like:
canvas.addEventListener( 'mousemove', function () {
var mouse = new THREE.Vector2();
var rect = canvas.getBoundingClientRect();
mouse.x = ( (event.clientX - rect.left) / rect.width ) * 2 - 1;
mouse.y = - ( (event.clientY - rect.top) / rect.height ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
}, false);

.setCapture and .releaseCapture in Chrome

I have an HTML5 canvas based Javascript component that needs to capture and release mouse events. In the control the user clicks an area inside it and drags to affect a change. On PC I would like the user to be able to continue dragging outside of the browser and for the canvas to receive the mouse up event if the button is released outside of the window.
However, according to my reading setCapture and releaseCapture aren't supported on Chrome.
Is there a workaround?
An article written in 2009 details how you can implement cross-browser dragging which will continue to fire mousemove events even if the user's cursor leaves the window.
http://news.qooxdoo.org/mouse-capturing
Here's the essential code from the article:
function draggable(element) {
var dragging = null;
addListener(element, "mousedown", function(e) {
var e = window.event || e;
dragging = {
mouseX: e.clientX,
mouseY: e.clientY,
startX: parseInt(element.style.left),
startY: parseInt(element.style.top)
};
if (element.setCapture) element.setCapture();
});
addListener(element, "losecapture", function() {
dragging = null;
});
addListener(document, "mouseup", function() {
dragging = null;
}, true);
var dragTarget = element.setCapture ? element : document;
addListener(dragTarget, "mousemove", function(e) {
if (!dragging) return;
var e = window.event || e;
var top = dragging.startY + (e.clientY - dragging.mouseY);
var left = dragging.startX + (e.clientX - dragging.mouseX);
element.style.top = (Math.max(0, top)) + "px";
element.style.left = (Math.max(0, left)) + "px";
}, true);
};
draggable(document.getElementById("drag"));
The article contains a pretty good explanation of what's going on, but there are a few gaps where knowledge is assumed. Basically (I think), in Chrome and Safari, if you handle mousemove on the document then, if the user clicks down and holds the mouse, the document will continue receiving mousemove events even if the cursor leaves the window. These events will not propagate to child nodes of the document, so you have to handle it at the document level.
Chrome supports setPointerCapture, which is part of the W3C Pointer events recommendation. Thus an alternative would be to use pointer events and these methods.
You might want to use the jquery Pointer Events Polyfill to support other browsers.

HTML5 drag and drop element over div with Hammer.js drag events

TL;DR
I want to use HTML5 drag and drop of an element to a container with drag Hammer.js events. However, there are conflicts.
Detailed description:
As presented in the attached figure, I have two containers:
Left: container with draggable elements
Right: container with Hammer.js events, namely drag, dragstart and dragend.
I want to drag and drop elements from the left container to the right one.
However, while dragging, when entering on the right container, the Hammer.js dragstart event is activated. After dropping the element, I apply the drag event on the right container. However, the Hammer.js drag event is activated and it considers the deltaX and deltaY from the previous dragstart event.
Hammer.js is being used with preventDefault: true:
Hammer(this.container, {preventDefault: true}).on('dragstart', function (event) { ... }
I have already used event.preventDefault() and event.stopPropagation() on the dragstart of the draggable element, without success.
I have also partially solved the problem. In the dragstart event of the Hammer.js container, I have added the following verification, in order to check if the source element and the target are the same. However, the drag in the right container only works on the second action, since the first one is ignored.
if (event.gesture.startEvent.srcEvent.srcElement != event.gesture.target) {
return false;
}
Any idea on how to prevent Hammer.js events while dragging elements using the HTML5 drag and drop API?
I want to use flags as a last resort, since Hammer.js events should be developed by third-parties.
Thanks for your help.
Hammer.js events should only be captured if they have previously been bound.
Try using a case statement...(this is from an app that I built recently) I can case the statement then break out or return false etc to prevent things. Theoretically though, if I unbind or exclude the event "drag" it should work anyway.
<script>
var hammertime = Hammer(document.getElementById('image-wrapper'), {
transform_always_block: true,
transform_min_scale: window.initScale,
transform_max_scale: 1,
drag_block_horizontal: true,
drag_block_vertical: true,
drag_min_distance: 0
});
//console.log(hammertime);
var posX = window.calcLeft, posY = window.calcTop,
lastPosX = window.calcLeft, lastPosY = window.calcTop,
bufferX = 0, bufferY = 0,
scale = window.initScale, last_scale,
rotation = window.rotationNeeded, last_rotation, dragReady = 0;
hammertime.on('touch drag dragend transform release mouseleave transformend pinchin pinchout', function (ev) {
elemRect = document.getElementById('the-image');
manageMultitouch(ev);
});
function manageMultitouch(ev) {
var pinchDirection;
ev.stopPropagation();
//console.log(ev.type);
switch (ev.type) {
case 'touch':
last_scale = scale;
last_rotation = rotation;
break;
case 'drag':
posX = ev.gesture.deltaX + lastPosX;
posY = ev.gesture.deltaY + lastPosY;
break;
case 'pinchin':
console.log('pinchin');
pinchDirection = "in";
break;
case 'pinchout':
console.log('pinchout');
pinchDirection = "out";
break;
case 'transform':
rotation = window.rotationNeeded;// rotation + ev.gesture.rotation;//we can change this to snap rotation eventually.
//console.log('Last Scale: ', last_scale);
scale = Math.max(hammertime.options.transform_min_scale, Math.min(last_scale * ev.gesture.scale, 1));
var propsImage = document.getElementById('the-image').getBoundingClientRect();
//console.log(propsImage);
var propsBox = document.getElementById('image-wrapper').getBoundingClientRect();
//console.log(propsBox);
break;
case 'transformend':
console.log('We are finished transforming.');
//when they finish transforming, we need to determinw what the new left reset position would be.
var propsImage = document.getElementById('the-image').getBoundingClientRect();
var propsBox = document.getElementById('image-wrapper').getBoundingClientRect();
//window.calcLeft = Math.round(window.preBounds.left - propsImage.left);
//console.log(ev.type);
//if (pinchDirection = "out") {
window.calcLeft = Math.round(window.calcLeft + ((propsImage.width - propsBox.width) / 2));
//} else if (pinchDirection = "in") {
//window.calcLeft = Math.round(window.calcLeft - ((propsImage.width - propsBox.width) / 2));
//}
//window.calcTop = Math.round(window.calcTop + ((propsImage.top - propsBox.top) / 2));
//console.log(window.calcLeft);
break;
case 'dragend':
//console.log('We are finished dragging.');
//console.log(window.calcLeft);
lastPosX = posX;
lastPosY = posY;
checkBounds();
break;
case 'mouseleave':
//console.log('Release!', posX, posY);
//checkBounds();
break;
}
<script>

Using TogetherJS Extensibility to Sync Changes to a Div

My goal is to add some code around TogetherJS to enable the synchronization (between TogetherJS users) of changes that are being made to a contenteditable div.
My question is how I could do this for a div - which seems like it would be a much easier functionality to implement but I can't currently wrap my head around it.
TogetherJS developers provided an example of how to do this for drawing on a canvas:
<canvas id="sketch"
style="height: 400px; width: 400px; border: 1px solid #000">
</canvas>
// get the canvas element and its context
var canvas = document.querySelector('#sketch');
var context = canvas.getContext('2d');
// brush settings
context.lineWidth = 2;
context.lineJoin = 'round';
context.lineCap = 'round';
context.strokeStyle = '#000';
We’ll use mousedown and mouseup events on the canvas to register our move() handler for the mousemove event:
var lastMouse = {
x: 0,
y: 0
};
// attach the mousedown, mousemove, mouseup event listeners.
canvas.addEventListener('mousedown', function (e) {
lastMouse = {
x: e.pageX - this.offsetLeft,
y: e.pageY - this.offsetTop
};
canvas.addEventListener('mousemove', move, false);
}, false);
canvas.addEventListener('mouseup', function () {
canvas.removeEventListener('mousemove', move, false);
}, false);
And then the move() function will figure out the line that needs to be drawn:
function move(e) {
var mouse = {
x: e.pageX - this.offsetLeft,
y: e.pageY - this.offsetTop
};
draw(lastMouse, mouse);
lastMouse = mouse;
}
And lastly a function to draw lines:
function draw(start, end) {
context.beginPath();
context.moveTo(start.x, start.y);
context.lineTo(end.x, end.y);
context.closePath();
context.stroke();
}
This is enough code to give us a very simple drawing application. TogetherJS has a “hub” that echoes messages between everyone in the session. It doesn’t interpret messages, and everyone’s messages travel back and forth, including messages that come from a person that might be on another page. TogetherJS also lets the application send their own messages like:
TogetherJS.send({
type: "message-type",
...any other attributes you want to send...
})
to send a message (every message must have a type), and to listen:
TogetherJS.hub.on("message-type", function (msg) {
if (! msg.sameUrl) {
// Usually you'll test for this to discard messages that came
// from a user at a different page
return;
}
});
The message types are namespaced so that your application messages won’t accidentally overlap with TogetherJS’s own messages.
To synchronize drawing we’d want to watch for any lines being drawn and send those to the other peers:
function move(e) {
var mouse = {
x: e.pageX - this.offsetLeft,
y: e.pageY - this.offsetTop
};
draw(lastMouse, mouse);
if (TogetherJS.running) {
TogetherJS.send({type: "draw", start: lastMouse end: mouse});
}
lastMouse = mouse;
}
Before we send we check that TogetherJS is actually running (TogetherJS.running). The message we send should be self-explanatory.
Next we have to listen for the messages:
TogetherJS.hub.on("draw", function (msg) {
if (! msg.sameUrl) {
return;
}
draw(msg.start, msg.end);
});
We don’t have to worry about whether TogetherJS is running when we register this listener, it can only be called when TogetherJS is running.
This is enough to make our drawing live and collaborative. But there’s one thing we’re missing: if I start drawing an image, and you join me, you’ll only see the new lines I draw, you won’t see the image I’ve already drawn.
To handle this we’ll listen for the togetherjs.hello message, which is the message each client sends when it first arrives at a new page. When we see that message we’ll send the other person an image of our canvas:
TogetherJS.hub.on("togetherjs.hello", function (msg) {
if (! msg.sameUrl) {
return;
}
var image = canvas.toDataURL("image/png");
TogetherJS.send({
type: "init",
image: image
});
});
Now we just have to listen for this new init message:
TogetherJS.hub.on("init", function (msg) {
if (! msg.sameUrl) {
return;
}
var image = new Image();
image.src = msg.image;
context.drawImage(image, 0, 0);
});
This worked surprisingly well for me - awesome performance (although this is for an intranet site).
For beginners (like me) to extending TogetherJS to your own apps, the "type" can be set to anything. It helps distinguish the function of this particular message/action pair from others. It is required as it is basically the title of the message. For "output", you can also name that anything (or have more than one). That will store data to be sent with the message.
The first section of code sends the message.
The second section of code listens for the message from other TogetherJS users on the same shared URL. The naming conventions between the "send" and "listen" events/functions must match (e.g., text-send)
Here is my solution:
$('#SourceText').keyup(function (event) {
// grab text for sending as a message to collaborate
var sharedtext = $('#SourceText').html()
//alert(sharedtext)
if (TogetherJS.running) {
TogetherJS.send({
type: "text-send",
output: sharedtext
});
console.log(sharedtext)
}
});
TogetherJS.hub.on("text-send", function (msg) {
if (! msg.sameUrl) {
return;
}
$('#SourceText').html(msg.output);
console.log(msg.output)
});

Event Listeners MSPointer are not firing

I am currently trying to learn Javascript and doing the following tutorial (http://www.sitepoint.com/creating-a-simple-windows-8-game-with-javascript-input-and-sound/) however I have run into an issue that I cannot get past.
I have created a canvas element, attached three listeners to the canvas to work with mouse clicks:
canvas.addEventListener("MSPointerUp", endAim, false);
canvas.addEventListener("MSPointerMove", adjustAim, false);
canvas.addEventListener("MSPointerDown", beginAim, false);
But my functions are never being called on PointerUp or Down or Move.
Below are the functions in question, also note that I have done "console.log" just to debug.. None of those are being even recorded to the console, which is why I am thinking that the events are not being triggered..
function beginAim(event){
console.log("Aim ahoy");
if (playerTurn == 1) {
if (!isAiming) {
aimStart = new createjs.Point(event.x, event.y);
isAiming = true;
}
}
}
function adjustAim(event){
console.log("adjustAim event called");
if (isAiming) {
var aimCurrent = new createjs.Point(event.x, event.y);
aimVector = calculateAim(aimStart, aimCurrent);
//ToDo: write text / show aim arror
console.log("Aiming... " + aimVector.x + "/" + aimVector.y);
}
}
function endAim(event){
if (isAiming) {
console.log("endAim Function called");
isAiming = false;
var aimCurrent = new createjs.Point(event.x, event.y);
aimVector = calculateAim(aimStart, aimCurrent);
playerFire = true;
}
}
function calculateAim(start, end){
var aim = new createjs.Point(
(end.x - start.x) / 80,
(end.y - start.y) / 80);
aim.x = Math.min(MAX_SHOT_POWER, aim.x);
aim.x = Math.max(0, aim.x);
aim.y = Math.max(-MAX_SHOT_POWER, aim.y);
aim.y = Math.min(0, aim.y);
return aim;
}
I knew this was going to be a simple issue.. The MSPointerUp /Down / Move are all for Windows8, this is why they never triggered.
I ended up switching to mousedown, mouseup, and mousemove to get the same results.
add to body or canvas to route touch events to JavaScript:
body, canvas {
-ms-user-select: none;
touch-action: none;
}
Then, you'll need to create a MSGesture object, set its target to canvas, also create a pointerdown listener:
var gesture = new MSGesture();
gesture.target = canvas;
canvas.addEventListener("pointerdown", beginAim, false)
in beginAim add a handler for pointerdown and add it to gesture like this:
if (event.type == "pointerdown") {
gesture.addPointer(e.pointerId);
return
}

Categories

Resources