jQuery/Javascript force / pressure on the mouse click - javascript

I was wondering if is there any way to get the pressure level (pressure user makes on clicking on mouse key/button) on click.
Any resource or links?
Sorry for my bad english, hope my question is clear and hope is not just utopia!

I realize that I'm bumping an old thread with something that wasn't relevant then, but I believe this will be useful to others in the future.
As many others on this thread have pointed out, almost all computer mice don't measure the pressure used, so you cannot measure it. However, there are different pointing devices than mice out there, like drawing tablets or trackpads. In Gecko-based browsers like Firefox, there is the non-standard mozPressure attribute on mouse events. You would use it sort of like this:
document.addEventListener('click', function (e) {
alert(e.mozPressure);
});
mozPressure is a value between 0.0 and 1.0 depending on how hard the mouse was depressed. If you're using a normal mouse or something else that doesn't detect pressure, then this will always be 0.
Reference.

The mouse (hardware) doesn't register how hard you click it, and javascript can't track something that doesn't exist.

It's clearly not a qustion about phisical pressure but a measure of how long the user is keeping mouse button down and increasing frequency of some effect based on that information. This is my take:
someButton.addEventListener('mousedown', function(e) {
if (e.button == 0) {
someRelevantParentContainer.mouse0Pressed = true;
window.addEventListener('mouseup', function() {
someRelevantParentContainer.mouse0Pressed = false;
}, {once : true});
const func = function() {
if (someRelevantParentContainer.mouse0Pressed && !someButton.disabled) {
// do something
return true;
}
else {
return false;
}
};
recurAction(func, 200);
}
});
function recurAction(func, startingTimeout, minTimeout = 50) {
if (!func()) {
return;
}
if (startingTimeout > minTimeout) {
setTimeout(function() {
const cont = func();
if (cont) {
recurAction(func, startingTimeout / 1.3);
}
}, startingTimeout);
}
else {
const inter = setInterval(function() {
if (!func()) {
clearInterval(inter);
}
}, minTimeout);
}
}

Related

"Wheel" event triggers more than once despite using throttle

i try to do something like this:
function throttle(fn, wait) {
var time = Date.now();
return function() {
if ((time + wait - Date.now()) < 0) {
fn();
time = Date.now();
}
}
}
function callback() {
//something
}
something.addEventListener("wheel", throttle(callback, 500));
When I use mousewheel it seems to work nice and triggers only once. The issue is when I use Macbook's touchpad this event triggers (depending on swipe's length) 1, 2 or 3 times at once. What's a problem?
Your code is fine, the problem is that when you "wheel" with a touchpad, you trigger the wheel event a lot, especially a lot of very small values.
For example, if you try to scroll this page with a touchpad, you will notice the smoothness of the scroll. That's because many events are fired with a degressive value.
A throttle is a good start but not enough. An upgrade would be to dismiss wheel events with a very small delta value, like this:
function throttle(fn, wait) {
var time = Date.now();
return function(event) {
// we dismiss every wheel event with deltaY less than 4
if (Math.abs(event.deltaY) < 4) return
if ((time + wait - Date.now()) < 0) {
fn(event);
time = Date.now();
}
}
}
function callback(event) {
// something
}
something.addEventListener("wheel", throttle(callback, 500));
It won't be "perfect" but close.
If you want a perfect result, some advanced maths is necessary. And when I mean advanced, I mean I would myself need one week or two full-time to implement it cleanly across all devices.
If you want to control the wheel to scroll from a screen A to a screen B, you should check out the css scroll snapping property.

When does a click become a hold?

I'm making a web app where a button's behavior is different if the user clicks vs holds the button. I have been experimenting with different timings and it got me wondering if there is any established standard for this kind of thing.
For clarification: I am wondering if there is an exact timing that is standard. Below is the code I am using with 150ms being the threshold for a hold.
function onMouseDown()
{
var holdTimeout = setTimeout(function()
{
//Hold code (also cancels click event)
}, 150);
var cancelHold = function()
{
clearTimeout(holdTimeout);
};
window.onmouseup = cancelHold;
}
function onClick()
{
//Click code
}
Answering exactly your question, hold becomes click. You could set the click event (it's release in fact), inside the mousedown event. Run the code below and try holding and release the mouse button.
document.getElementById("click").addEventListener('mousedown', (e) => {
var i = 0;
var int = setInterval(() => {
console.log("hold " + i++);//<-- actions when we hold the button
}, 200)
document.getElementById("click").addEventListener("click", () => {
clearInterval(int);
console.log("release")//<-- actions when we release the button
})
});
<div id="click">click</div>
In this case, if we hold the button less that 200 milliseconds, just the click (release) event is fired.

jQuery | Is calling setTimeout on mousemove bad practice/inefficient?

This code determines if the user is online :
/* User online status */
var online = true;
var activeTimeout = setTimeout(_setUserInactive, 5000);
$(document).on("mousemove keydown keyup click", function () {
clearTimeout(activeTimeout);
activeTimeout = setTimeout(_setUserInactive, 5000);
if (!online) {
_setUserActive();
}
});
Pretty simple. But, is this going to cause performance issues? It will call every time the mouse is moved. Thanks.

JavaScript touch event updates for force or radius

JavaScript touch events contain properties for radius and force. Unfortunately it appears that events aren't generated when either property changes. Events are only triggered for things like touch start, move or end. Can anyone think of a way to get more updates on change of touch size?
Currently to get radius updates I have to wiggle my finger to trigger the touch move event, but I would prefer a software solution.
I had the same issue and then discovered this blog post: http://blog.framerjs.com/posts/prototyping-3D-touch-interactions.html
In a nutshell, we need to use touchstart event to capture the touch event, assign the event to a variable and then use setInterval to get the force value:
var el = document.getElementById('myElement');
var currTouch = null;
var currTouchInterval = null;
attachListeners = function () {
el.addEventListener('touchstart', enterForceTouch, false);
el.addEventListener('touchend', exitForceTouch, false);
}
enterForceTouch = function (evt) {
evt.preventDefault();
currTouch = evt;
currTouchInterval = setInterval(updateForceTouch, 10); // 100 times per second.
}
updateForceTouch = function() {
if (currTouch) {
console.log(currTouch.touches[0].force); // Log our current force value.
}
}
exitForceTouch = function (evt) {
evt.preventDefault();
currTouch = null;
clearInterval(currTouchInterval);
}
attachListeners();

Timed long press in Javascript within jQuery phonegap app

There is a good example for doing long press in Javascript here: Long Press in JavaScript?
But it does not provide for knowing the duration of the press.
If I want to do different things based on the length of the press I cant use the pattern in that post.
I was trying to do something similar by saving current time in a variable on('mousedown')
and then calculating the time difference on('mouseup').
this works fine within a normal Javasript page in a "normal" browser.
However within my phonegap app something happens,
looks like the mouseup event is not being called if the finger is kept on the screen for a long duration (say 5 sec..).
Is this some native mobile browser behavior? Can I override it somehow?
I am using plain jQuery not jQuery mobile.
Any ideas anyone?
You could have a look at how the taphold and vmouseup (handleTouchEnd() line 752) events are implemented in jQuery mobile source code.
Since it is already tested and implemented I'd suggest to use jquery mobile instead of jquery and modify (since it already handles all the 'quirks' related each mobile browser), and change the code as you need.
You can check the time to identify Click or Long Press [jQuery]
function AddButtonEventListener() {
try {
var mousedowntime;
var presstime;
$("button[id$='" + buttonID + "']").mousedown(function() {
var d = new Date();
mousedowntime = d.getTime();
});
$("button[id$='" + buttonID + "']").mouseup(function() {
var d = new Date();
presstime = d.getTime() - mousedowntime;
if (presstime > 999/*You can decide the time*/) {
//Do_Action_Long_Press_Event();
}
else {
//Do_Action_Click_Event();
}
});
}
catch (err) {
alert(err.message);
}
}
Note that this solution is usefull if you do not use jQuery Mobile for some reason.
I used the article Fast Touch Event Handling and just added a piece of code
$.event.special.tap = {
distanceThreshold: 10,
timeThreshold: 350,
setup: function () {
var self = this,
$self = $(self);
// Bind touch start
$self.on('touchstart', function (startEvent) {
// Save the target element of the start event
var target = startEvent.target,
touchStart = startEvent.originalEvent.touches[0],
startX = touchStart.pageX,
startY = touchStart.pageY,
threshold = $.event.special.tap.distanceThreshold,
timeout,
expired = false;
function timerFired() {
expired = true;
}
function removeTapHandler() {
clearTimeout(timeout);
$self.off('touchmove', moveHandler).off('touchend', tapHandler).off('touchcancel', removeTapHandler);
};
function tapHandler(endEvent) {
removeTapHandler();
if (target == endEvent.target) {
if (expired) {
$.event.simulate('longtap', self, endEvent);
} else {
$.event.simulate('tap', self, endEvent);
}
}
};
// Remove tap and move handlers if the touch moves too far
function moveHandler(moveEvent) {
var touchMove = moveEvent.originalEvent.touches[0],
moveX = touchMove.pageX,
moveY = touchMove.pageY;
if (Math.abs(moveX - startX) > threshold || Math.abs(moveY - startY) > threshold) {
removeTapHandler();
}
};
// Remove the tap and move handlers if the timeout expires
timeout = setTimeout(timerFired, $.event.special.tap.timeThreshold);
// When a touch starts, bind a touch end and touch move handler
$self.on('touchmove', moveHandler).on('touchend', tapHandler).on('touchcancel', removeTapHandler);
});
}
};
So, now I have a tap and a longtap events

Categories