Recording touch coordinates in canvas animations - javascript

I'm making this mini-game in HTML5 canvas using javascript's requestAnimationFrame.
function animate() {
frame = requestAnimationFrame( animate );
render();
}
It's destined to be a Cordova application, so I have to record touch input.
The game starts when the screen is pressed
document.addEventListener('touchstart',run);
It stops when the finger is removed.
I'm now looking for a way to record the touch's x and y coordinates, in order to display the finger's position smoothly on the screen.
So I was thinking about getting the x and y coordinates, and making an arc on this place in the
render()
function
But how could I permanently get these coordinates, or is there another way of doing this?
Thanks!!

You can refer this..
Is there an equivalent to e.PageX position for 'touchstart' event as there is for click event?
$(document).on('touchstart', 'body', function(e) {
var xPos = e.originalEvent.touches[0].pageX;
var yPos = e.originalEvent.touches[0].pageY;
});

Related

Is it possible to control the mouse tracking speed (how much the cursor moves in response to motion of the mouse) using JavaScript

I am new to Javascript.
I want to run an online (in-browser) experiment that requires users to move a cursor through moving targets. I have code to collect mouse position:
document.onmousemove = handleMouseMove;
setInterval(catchDots, 1); // setInterval repeats every X ms -> 1000 Hz
​
function handleMouseMove(event) {
var eventDoc, doc, body;
​
event = event || window.event; // IE-ism
mousePos = {
x: event.pageX,
y: event.pageY
};
}
However, I would like to be able to control the mouse/trackpad tracking speed, (i.e., the amount the cursor moves in response to motion of the mouse/finger on a trackpad). I would have thought that this would require either 1) being able to control the tracking speed or 2) knowing the tracking speed to be able to counter as appropriate. Is this possible?
Thanks in advance

How to track the position of the mouse on X-axis in JavaScript?

I want to know how to track the position of the mouse on X-axis on the screen. Based on limited knowledge of Java/Processing, it is something similar to mouseX in Java. In addition, I want to rotate an image element based on the position of the mouse on X-axis. It would be nice to receive some pieces of advice.
Track the mouse position in the X axis is done with an eventListener (the mousemove event)
This listener uses a callback function which should change the transform (rotate) css property of your element.
// DOM accessor to your HTML element
const rotatingE = document.getElementById('my-rotating-el')
// Event Listener
document.addEventListener('mousemove', e => {
// Callback function
const mX = e.clientX / window.innerWidth * 360
rotatingE.style.transform = 'rotate('+ mX +'deg)'
})
I've made a quick example here
a popular library/framework that is similar to Processing is P5.js (developed by the same people but for javascript) which can handle this for you
but in vanilla javascript, you would need an event listener
var mouse = {
x: undefined,
y:undefined
};
window.addEventListener("mousemove", function(event) {
mouse.x = event.x;
mouse.y = event.y;
});
what this does is listens for a mouse movement, and then records it to an object
then to take the mouseX position you can write
var mouseX = mouse.x;
or you can directly take it from
mouse.x;
//still the same

How do I make a HTML canvas rectangle resize along with mouse drag?

I am creating a web-based annotation application for annotating images via the HTML canvas element and Javascript. I would like the user to mouse down to indicate the start of the rectangle, drag to the desired end coordinate and let go to indicate the opposite end of the rectangle.
Currently, I am able to take the starting coordinates and end coordinates to create a rectangle on the image with the context.rects() function, however as I am uncertain on how to resize a specific rectangle on the canvas, that leaves me with the rectangle only being drawn after the user has released the mouse click.
How would I be able to resize a specific rectangle created onmousedown while dragging?
The following is the code snippet that performs the function:
var isMouseDown = false;
var startX;
var startY;
canvas.onmousedown = function(e) {
if(annMode){
isMouseDown = true;
var offset = $(this).offset();
startX = parseInt(e.pageX - offset.left);
startY = parseInt(e.pageY - offset.top);
}
};
canvas.onmousemove = function(e) {
if(isMouseDown) {
var offset = $(this).offset();
var intermediateX = parseInt(e.pageX - offset.left);
var intermediateY = parseInt(e.pageY - offset.top);
console.log(intermediateX);
}
};
canvas.onmouseup = function(e) {
if(annMode&&isMouseDown){
isMouseDown = true;
var offset = $(this).offset();
var endX = parseInt(e.pageX - offset.left);
var endY = parseInt(e.pageY - offset.top);
var width = endX - startX;
var height = endY - startY;
context.strokeStyle = "#FF0000";
context.rect(startX, startY, width, height);
context.stroke();
}
isMouseDown = false
};
Here my handy-front-end scripts come in handy!
As I understood the question, you wanted to be able to move your mouse to any point on the canvas, hold the left mouse button, and drag in any direction to make a rectangle between the starting point and any new mouse position. And when you release the mouse button it will stay.
Scripts that will help you accomplish what you are trying to do:
https://github.com/GustavGenberg/handy-front-end/blob/master/README.md#canvasjs
https://github.com/GustavGenberg/handy-front-end/blob/master/README.md#pointerjs
Both scripts just makes the code a lot cleaner and easier to understand, so I used those.
Here is a fiddle as simple as you can make it really using
const canvas = new Canvas([]);
and
const mouse = new Pointer();
https://jsfiddle.net/0y8cbao3/
Did I understand your question correctly?
Do you want a version with comments describing every line and what is does?
There are still some bugs at the moment but im going to fix those soon!
EDIT
After reading your questions again, I reacted to: "...however as I am uncertain on how to resize a specific rectangle on the canvas...".
Canvas is like an image. Once you have drawn to it, you can NOT "resize" different shapes. You can only clear the whole canvas and start over (ofcourse you can clear small portions too).
That's why the Canvas helper is so helpful. To be able to "animate" the canvas, you have to create a loop that redraws the canvas with a new frame each 16ms (60 fps).
The canvas API does not preserve references to specific shapes drawn with it (unlike SVG). The canvas API simply provides convenient functions to apply operations to the individual pixels of the canvas element.
You have a couple options to achieve a draggable rectangle:
You can position a styled div over your canvas while the user is dragging. Create a container for your canvas and the div, and update the position and size the div. When the user releases, draw your rectangle. Your container needs to have position: relative and the div needs to be absolutely positioned. Ensure the div has a higher z-index than the canvas.
In your mouse down method, set div.style.display to block. Then update the position (style.left, style.top, style.width, and style.height) as the mouse is dragged. When the mouse is released, hide it again (style.display = 'none').
You can manually store references to each item you want to draw, clear the canvas (context.clearRect), and redraw each item on the canvas each frame. This kind of setup is usually achieved through recursive usage of the window.requestAnimationFrame method. This method takes a callback and executes on the next draw cycle of the browser.
The first option is probably easier to achieve in your case. If you plan to expand the capabilities of your app further, the 2nd will provide more versatility. A basic loop would be implemented as so:
// setup code, create canvas & context
function mainLoop() {
context.clearRect(0, 0, canvas.width, canvas.height);
/** do your logic here and re-draw **/
requestAnimationFrame(mainLoop);
}
function startApp() {
requestAnimationFrame(mainLoop)
}
This tutorial has detailed explanation of event loops for HTML canvas: http://www.isaacsukin.com/news/2015/01/detailed-explanation-javascript-game-loops-and-timing
I also have a fully featured implementation on my GitHub that's part of rendering engine I wrote: https://github.com/thunder033/mallet/blob/master/src/mallet/webgl/webgl-app.ts#L115

Mouse coordinates over HTML page

i am trying to use an example from the three.js page's, the voxel painter one. In this example the mouse coordinates's are used to move a roll-over helper that indicates the position where a box will be placed after the click.
mouse.set((event.clientX/window.innerWidth)*2-1, -(event.clientY/window.innerHeight)*2+1);
This piece of code calculates the position of the mouse all over the page.
I have added other div elements in the page such that the total amount of space for the webGL canvas is different from the total amount of space in the page, the new dimensions of the webGL canvas are 95% of the total height and 85% of the total width.
Now, the mouse position's over my webGL canavas is obviously different therefore the roll-over helper does not overlap anymore the position of the mouse. How have i to modify the above piece of code?
You could use jQuery to detect mouse position which works off any jQuery object passed to it.
$(function() {
var xCoord, yCoord;
$(document).on("mousemove", function(event) {
xCoord = event.pageX;
yCoord = event.pageY;
console.log("x: "+ xCoord+ ", y: "+ yCoord);
} );
} );
Just change the jQuery selector to your canvas and jQuery will handle the rest.
Hope this helps!
If you want the global position of the mouse cursor on your page, you should rather use the page coordinates like this:
event.pageX
event.pageY

Tracking relative mouse position without a mousemove event

I need to track mouse position relative to a <canvas> element in my app. Currently, I have a mousemove event listener attached to the <canvas> that updates my mouse position whenever it fires, using offsetX/offsetY when available, or layerX/layerY when the offsetX/Y is not available. Using offsetX/Y or layerX/Y gives me mouse coordinates relative to my <canvas>, which is exactly what I want. As my app works its magic, various CSS 3d transformations get applied to the <canvas>, and even when <canvas> is very transformed, offsetX/Y still gives me accurate coordinates within the <canvas>'s local, transformed coordinate-space.
That's kind of confusing, so I'll try stating an example. If my <canvas> is 100px in both width and height, and is located at (0,0) relative to the browser viewport, and I click at (50,50) (in viewport coords), that corresponds to (50,50) in my <canvas>, and 50 is the value that is (correctly) returned via offsetX and offsetY. If I then apply transform: translate3d(20px,20px,0px) to my <canvas> and click at (50,50) (in viewport coords), since my canvas has been shifted 20px down and 20px to the right, that actually corresponds to (30,30) relative to the <canvas>, and 30 is the value that is (correctly) returned via offsetX and offsetY.
The problem I'm facing is what to do when the user is not physically moving the mouse, yet the <canvas> is being transformed. I'm only updating the position of the mouse on mousemove events, so what do I do when there is no mousemove?
For example. My mouse is positioned at (50,50) and no transformations are applied to the <canvas>. My this.mouseX and this.mouseY are both equal to 50; they were saved at the final mousemove event when I moved the mouse to (50,50). Without moving the mouse at all, I apply the above transformation (transform: translate3d(20px,20px,0px)) to my <canvas>. Now, I need this.mouseX and this.mouseY to each be equal to 30, as that is my mouse's new position relative to the current transformation of <canvas>. But this.mouseX and this.mouseY are still equal to 50. Since I never moved the mouse, there was no mousemove event fired, and those saved coords never got updated.
How can I deal with this? I thought about creating a new jQuery event, manually assigning some properties (pageX and pageY?) based on my old/previous mouse position, and then triggering that event, but I don't think that's going to cause the browser to recalculate the offsetX and offsetY properties. I've also been thinking about taking the known old/previous mouse position and multiplying it by my transformation matrix, but that's going to get real complicated since my mouse coordinates are in 2d-space, but the transformations I'm applying to <canvas> are all 3d transformations.
I guess really, what I want to do is take my known 2d page position and raycast it into the 3d space and find out where I'm hitting the transformed <canvas>, all in javascript (jQuery is available).
Is this possible? Does this even make sense?
Works in all browsers
var mouseX=0;
var mouseY=0;
var canvas = document.querySelector('#canvas');
var rect = canvas.getBoundingClientRect();
document.onmousemove = function(e) {
mouseX=e.clientX-rect.left;
mouseY=e.clientY-rect.top;
};
function updateCoords() {
mouseX=e.clientX-mouseX;
mouseY=e.clientY-mouseY;
setTimeout(updatecoords,10);
}
Now we can call updateCoords() function once to repeatedly check for new position.
updateCoords();
You can add your code inside the updateCoords() function and it will be executed each 10 milliseconds
Concept: mouseX and mouseY variables get updated on mousemove event, and also get updated when there is any change in the canvas position.
It looks like you want to refresh your mouseposition-values even if you don't move your mouse. You should try something like this:
var event = '';
var counter = 1;
$(function(e){
event = e;
window.setInterval(refresh, 10);
});
$(document).mousemove(function(e){
event = e;
refresh;
});
function refresh(){
counter++;
$('#mousepos').val("event.pageX: " + event.pageX + ", event.pageY: " + event.pageY + ", counter: " + counter)
}
The counter is just for visualisation of the refresh. You can set the interval to everything you want (10 = 10ms = 0.01s) Just move everything from your .mousemove() event into this refresh() function and call it properly and your mouse position should update even if you don't move your mouse.
Look at this fiddle for a life example: http://jsfiddle.net/82cmxw8L/1
EDIT:
Because my fiddle didn't work for the asker, i updated it: http://jsfiddle.net/82cmxw8L/8/
New is, that the mouseposition is now set every 0.1 Second, no matter what, rather than being updated only when the mouse moves.

Categories

Resources