I'm logging the mouse movements in a web app.
I'd like to detect the mouse acceleration on a platform (e.g. Windows). Is it possible to do it from javascript, even just in an approximated way? I could ask the user to check their settings with a questionnaire, but it would be much better to detect it automatically.
Cheers
Check distance the mouse has moved over a set interval of time:
var mX:Number = _xmouse;
var mY:Number = _ymouse;
function checkDistance()
{
clear();
//trace('new distance: ' + Math.sqrt(Math.pow((mY - _ymouse), 2) + Math.pow((mX - _xmouse), 2)));
lineStyle(1, 0x000000);
moveTo(mX, mY);
lineTo(_xmouse, _ymouse);
mX = _xmouse;
mY = _ymouse;
}
setInterval(checkDistance, 1000);
from http://www.kirupa.com/forum/showthread.php?t=332961
Related
I'm running into a bit of an odd issue with Paper.js - I'm using the library to scale the "petals" of a randomly generated flower while audio plays.
The issue crops up if the flower is "growing" and the user navigates to a different tab in the browser. Even though it appears that the onFrame event is not firing when the window is out of view, whichever petal is currently scaling at the time will continue to scale indefinitely.
I even tried using a special js library to determine if the window is in view and still wasn't able to get the petals to stop scaling.
You can view a demo here, as I was not even able to replicate this in a Paper sketch: https://demos2.paperbeatsscissors.com/
Also including my onFrame code here in case the problem is obvious to someone:
view.onFrame = function(event) {
// See if something is playing
if (playing > -1) {
// Get the active flower
var activeFlower = garden[playing],
activeData = activeFlower.data;
// Active layer and petal
var activeLayer = getEl(activeFlower, activeData.lIndex),
activePetal = getEl(activeLayer, activeData.pIndex);
// Variables
var time = activeData.audio.seek(),
scaleAmount = (1 / (activeData.timing / event.delta.toFixed(3))) * 2;
// Petal progression
if (!activeData.completed) {
if (activePetal.scaling.x < 1 && activePetal.scaling.y < 1) {
activePetal.pivot = {x: 0, y: activePetal.height / 2};
activePetal.scaling.x = activePetal.scaling.x + scaleAmount;
activePetal.scaling.y = activePetal.scaling.y + scaleAmount;
} else {
if (activeData.pIndex < (activeLayer.children.length - 1)) {
// If the petal is scaled, jump to a new petal
activeData.pIndex += 1;
} else {
if (activeData.lIndex > 0) {
// When all petals are bloomed, jump to a new layer
activeData.pIndex = 0;
activeData.lIndex -= 1;
} else {
// Set the flower as completed
activeData.completed = true;
}
}
}
}
activeFlower.rotate(.125, activeData.center);
// Reset the playing variable if the audio clip is complete and the flower has completed
if (!activeData.audio.playing() && time === 0 && activeData.completed) {
playing = -1;
}
}
}
Really stumped on this one so any help is greatly appreciated!
I think that your problem is coming from the fact that you base your scaling calculation on event.delta which represents the time elapsed since the last event fired.
The thing is that, if I'm not mistaken, under the hood, Paper.js onFrame event relies on requestAnimationFrame which does not fire when the tab if inactive.
So when you switch tab, wait for a while and get back to your tab event.delta value is big and your scaling value too, hence the size of your petals. This basic sketch showcase this behavior.
So in my opinion, you should simply check event.delta value and limit it if it's too high.
I'm currently building a menu that is also draggable and I'm using the following on each individual tab:
(mousedown)="dragging = false"
(mousemove)="checkMouseMove($event)"
(mouseup)="changeRoute('forms')"
Change Route looks like this:
changeRoute(routeName: string) {
// manual reset for dragging.
if (this.dragging) {
return;
}
Past this is just my routing and switch statement's that correctly will change route and apply styling etc.
Previously inside the mousemove event I just had dragging = true but the problem with this is that even the slightest movement will mean that a click does not occur when it's likely to be intended to.
My first instinct was that I need to add a buffer to the amount of space it will need to move to be called a drag but given the output events I'm not sure how to achieve this.
checkMouseMove(event) {
console.log(event);
}
This event provides me with the following output:
How can I use these events in conjunction with my checkMouseMove / Component to only change dragging after a reasonable amount of movement?
You can save the last mouse position and calculate the distance the cursor moved.
Based on this distance you can filter small and unwanted drags.
var lastEvent;
function checkMouseMove (event){
var dx = 0;
var dy = 0;
if (lastEvent) {
dx = event.clientX - lastEvent.clientX;
dy = event.clientY - lastEvent.clientY;
}
var d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
if (d > 5) { /* handle mouse move here */ }
lastEvent = event;
}
You can also use any other non euclidean heuristics like Manhattan or Chebyshev.
I am developing a WebGL application. For example, I have a sphere object that uses orbit controls for Zoom in/out.
Now I want to setup an event for the mousewheel. When zooming on my current WebGL block corresponding map location it can be zoomed in/out (used inline-block) for maps and WebGL. But the problem is that first of all my event is being triggered when I use the mousewheel. I also want to know whether my event logic is correct or not.
root.addEventListener('mousewheel', mousewheel, false);
function mousewheel(event) {
var mX = (event.wheeldetailX/width)* 2 - 1;
var mY = (event.wheeldetailY/height)* 2 + 1;
var WebGLZoom = new THREE.Vector3(mX, mY, 1);
var raycaster = new THREE.Raycaster();
raycaster.setFromCamera(WebGLZoom, camera);
WebGLZoom.sub(camera.position);
var mapzoom = map.getZoom();
if (WebGLZoom.z <= 5 && WebGLZoom.z > 2) {
map.setZoom(17);
} else if (WebGLZoom.z <= 2 && WebGLZoom.z > 0.0) {
map.setZoom(19);
} else {
map.setZoom(14);
}
}
You can use the wheel event like so.
document.addEventListener('wheel', function(event){
console.log(event.deltaY);
}, false);
This will result in a console log every time your mousewheel scrolls over the document. The deltaX and deltaY properties of the MouseWheel event are especially useful to figure out exactly how much the user scrolled and in which direction.
The event to use is wheel. You can find a working example here.
I'm trying to manually create a parallax effect of sorts, and so far here's my JavaScript:
var bottom = document.getElementById("bottom");
var top = document.getElementById("top");
window.addEventListener("deviceorientation", function(e) {
var gamma = e.gamma;
var beta = e.beta;
$(bottom).css('left',(gamma/2)+'px').css('top',(beta/2)+'px');
$(top).css('left',(gamma)+'px').css('top',(beta)+'px');
});
So far its working great and I have the effect I want, but the starting position of the device is not quite what I want. Currently the alpha, beta, and gamma values are only at 0,0,0 if the device is flat on the table. What I want to do is that when you load the page, that position is taken as 0,0,0.
For example, if I am reading my phone in my hand, then of course my phone is going to be at an angle already, and I want to take this starting position as 0,0,0 when the page is loaded.
So to put that into some sort of pseudo code, here's what I'm trying to achieve:
gammaOnLoad and betaOnLoad = initial device orientation
gammaCurrent and betaCurrent = e.gamma and e.beta (from event listener)
gammaDifference and betaDifference = Math.abs(gammaOnLoad - gammaCurrent)
$(elem).css('left', gammaDifference + 'px').css('top', betaDifference + 'px');
So essentially you take in the values when loading the page and use those as 0, your point of origin. This means that whatever angle your phone is at, when you load the page the image will always look normal and from there it will begin the parallax effect.
I wanted to do the same thing as you. This is very basic, but it seems to work:
$(document).ready(function() {
var origLR, origFB;
function setOrigin(eventData) {
origLR = eventData.gamma;
origFB = eventData.beta;
}
if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', setOrigin, false);
setTimeout(function() {
window.removeEventListener('deviceorientation', setOrigin, false);
window.addEventListener('deviceorientation', function(eventData) {
var tiltLR = eventData.gamma,
tiltFB = eventData.beta;
tiltLR = (origLR - tiltLR);
tiltFB = (origFB - tiltFB);
deviceOrientationHandler(tiltLR, tiltFB);
}, false);
}, 100);
};
function deviceOrientationHandler(tiltLR, tiltFB) {
$('.bottom').css('transform','translateX(' + (tiltLR/5) + 'px) translateY(' + (tiltFB/5) + 'px)');
$('.top').css('transform','translateX(' + (tiltLR/2.5) + 'px) translateY(' + (tiltFB/2.5) + 'px)');
}
});
I added an event listener for 100ms that sets the initial device orientation values, then removed it and replaced it with one that calculates the difference between initial and current.
This can probably be more efficient, I'm not a particularly experienced programmer.
I'm using Copperlicht, and I want to create a usable FPS. The demo controls shows why the browser environment makes this a pain.
In order to implement FPS camera control, you need to track the relative mouse position - in other words, its motion, not its absolute screen coordinates. The mouse can leave the browser at any time (rightfully so) and can't be tracked, unless the user initiates a drag event inside the page. Click events change focus and prevent the application from using mouse data as input.
The mouse position can be tracked during drag, but this requires the user to hold down their left mouse button. This isn't good since left clicking is usually used for other things. Holding the button down is also tiring and cumbersome.
The only thing I can think of is automating the middle mouse button. A middle mouse button press keeps focus in the browser, and keeps left/right click events outside the browser window in the browser's focus. Is it possible to cause middle mouse button to stay pressed using JavaScript?
If not, is there a "pure" solution to this ? I'd rather not go to flash or Java or a plugin as an answer.
This thread is a nice reading on this topic. It seems like prototypes for this functionality are at least suggested for Firefox and Chrome.
How about making the window fullscreen and then pausing the game if the cursor moves out of the window? I know this doesn't really solve the problem, but it's the best I can think of, without using a plugin of some sort.
It's kind of cheating, but going to about:flags in Chrome and enabling "FPS counter" works for me, :) (but it's not doing it for all browsers nor inside your WebGL app).
I found this example code at
http://bitdaddys.com/javascript/example3run.html
<html>
<head>
<title>JavaScript Example of Mouse Position Tracking</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<form name=thisform>
<table border=0>
<tr><td colspan=2>Position Of Cursor</td></tr>
<tr><td>X <input type=text name=x value=""></td>
<td>Y <input type=text name=y value=""></td>
</tr>
</table>
</form>
<script type=text/javascript>
var isIE = document.all?true:false;
if (!isIE) document.captureEvents(Event.MOUSEMOVE);
document.onmousemove = getMousePosition;
function getMousePosition(mp) {
var _x;
var _y;
if (!isIE) {
_x = mp.pageX;
_y = mp.pageY;
}
if (isIE) {
_x = event.clientX + document.body.scrollLeft;
_y = event.clientY + document.body.scrollTop;
}
document.thisform.x.value=_x;
document.thisform.y.value=_y;
return true;
}
</script>
</body>
</html>
We need the window to be able to capture the mouse, as it is seen with some browser plugins, maybe in Java. Flash doesn't have this ability, AFAIK.
As a sidenote, when captured to "get the mouse back" you have to press ESC, and this can be annoying when the app doesn't inform the user properly.
(this is the only solution i've seen so far could work for my game project, doing an FPS too)
Implement a Plugin for each browser you intend to support. AFAIK, this is the way they solved the problem with "Quake Live".
Chrome / Chromium -> PPAPI
Firefox & Opera -> NPAPI
IE -> ActiveX
Safari -> Safari plugin development
Btw, the link Daniel Baulig gave you has a nice pointer and solves this problem (on the long run).
At this point in time (Oct 2011) the only way to get real First Person Shooter-style controls is via a browser plugin. Depending on your needs you might also be able to get away with a simple click-and-drag scheme like I'm currently using in my Quake 3 demo, but if you are building an actual game and not a pretty tech demo this is probably not sufficient.
(Note: That's actually what Google did for their GWT port of Quake 2. You have to use the CTRL key to fire, since clicking is used to move your view.)
In the near future, however, we should be receiving a "MouseLock" API that is basically custom-built for this purpose. You can read up on it's progress at Seth Ladd's Blog. Once that comes out we'll have a lot more options for game controls available to us. (Would also help with things like RTS games)
Right here right now :
I make one with push/pop matrix with glmatrix 0.9 also version 2.0 webgl & glmatrix .
Secret - Must translate to zero , rotate and then translate to map position. You have all parameters for first person controler.
See:opengles 1.1. / webgl 1.0 / glmatrix 0.9
or see this example with full colizion.
WebGl 2 / glmatrix 2 Example's (also First Person controller):
Download from bitBucket
Live example
Out of context :
////////////////////////////////////////////////////////
// Somewhere in draw function ....
////////////////////////////////////////////////////////
mat4.identity(object.mvMatrix);
this.mvPushMatrix(object.mvMatrix,this.mvMatrixStack);
////////////////////////////////////////////////////////
if (App.camera.FirstPersonController==true){camera.setCamera(object)}
////////////////////////////////////////////////////////
mat4.translate(object.mvMatrix, object.mvMatrix, object.position.worldLocation );
mat4.rotate(object.mvMatrix, object.mvMatrix, degToRad(object.rotValue), object.rotDirection.RotationVector );
....
End of Draw function
Content of SetCamera :
var camera = new Object();
/* Set defaults */
camera.pitch = 0;
camera.pitchRate = 0;
camera.yaw = 0;
camera.yawRate = 0;
camera.xPos = 0;
camera.yPos = 0;
camera.zPos = 0;
camera.speed = 0;
camera.yawAmp = 0.05;
camera.pitchAmp = 0.007;
keyboardPress = defineKeyBoardObject();
camera.setCamera = function(object) {
/* Left Key or A */
if (keyboardPress.getKeyStatus(37) || keyboardPress.getKeyStatus(65) || App.camera.leftEdge == true) {
camera.yawRate = 20;
if (App.camera.leftEdge == true) camera.yawRate = 10;
}
/* Right Key or D */
else if (keyboardPress.getKeyStatus(39) || keyboardPress.getKeyStatus(68) || App.camera.rightEdge == true) {
camera.yawRate = -20;
if (App.camera.rightEdge == true) camera.yawRate = -10;
}
else {
// camera.yawRate = 0;
}
/* Up Key or W */
if (keyboardPress.getKeyStatus(38) || keyboardPress.getKeyStatus(87)) {
camera.speed = 0.03;
}
/* Down Key or S */
else if (keyboardPress.getKeyStatus(40) || keyboardPress.getKeyStatus(83)) {
camera.speed = -0.03;
}
else {
camera.speed = 0;
}
/* Page Up
if (keyboardPress.getKeyStatus(33)) {
camera.pitchRate = 100;
}
/* Page Down
else if (keyboardPress.getKeyStatus(34)) {
camera.pitchRate = -100;
}
else {
camera.pitchRate = 0;
}
*/
/* Calculate yaw, pitch and roll(x,y,z) */
if (camera.speed != 0) {
camera.xPos -= Math.sin(degToRad(camera.yaw)) * camera.speed;
camera.yPos = 0;
camera.zPos -= Math.cos(degToRad(camera.yaw)) * camera.speed;
}
camera.yaw += camera.yawRate * camera.yawAmp ;
camera.pitch += camera.pitchRate * camera.pitchAmp ;
mat4.rotate(object.mvMatrix, object.mvMatrix, degToRad(-camera.pitch), [1, 0, 0]);
mat4.rotate(object.mvMatrix, object.mvMatrix, degToRad(-camera.yaw), [0, 1, 0]);
// mat4.translate(object.mvMatrix, object.mvMatrix, [camera.yaw, -camera.pitch, 0]);
mat4.translate(object.mvMatrix, object.mvMatrix, [-camera.xPos , -camera.yPos , -camera.zPos ]);
camera.yawRate = 0;
camera.pitchRate = 0;
};
This code allows you to draw 3D objects and folders easily
and quickly.Under the principle of one object one line.
webgl 3d wourld engine framework zlatnaspirala
First person web site look.
Used lib :
High performance matrix and vector operations for WebGL