I had implemented zoom in/out an image using mousewheel event which is successfully working. But the behavior is different when I do that with touchpad(using two fingers to zoom in/out). How to differentiate beetween mousewheel event and touchpad events.
I had implemented zoom in/out an image using mousewheel event which is successfully working. But the behavior is different when I do that with touchpad(using two fingers to zoom in/out). How to differentiate beetween mousewheel event and touchpad events.
Share Improve this question edited Jan 31, 2020 at 11:27 user2083041 asked May 7, 2018 at 6:39 user2083041user2083041 5231 gold badge10 silver badges32 bronze badges3 Answers
Reset to default 3The same wheel event unfortunately fires for both pinch and mouse wheel, so it doesn't seem possible at this time to use a different event.
However, I found that the mouse wheel tends to trigger the e.deltaY
number in a larger way than pinching.
Thus, I have a listener like so:
const handleZoom = (e) => {
e.preventDefault();
// ignore mouse wheel events that have bigger steps
if (Math.abs(e.deltaY) > 25) {
return;
}
// do what you want to do with pinching here
}
document.addEventListener("wheel", handleZoom);
You can play with the 25
variable to suit your own needs. But for the most part, I noticed that pinch movements are usually much more subtle and have a delta closer to 0, whereas mouse wheel events usually trigger a larger scroll.
Touchpad two-finger gestures always emit wheel
event. However you can distinguish touchpad from mouse event by looking at the deltas and making some reasonable assumptions, and you can distinguish zoom from scroll by checking the ctrlKey
value of the event. You can also determine scroll direction by looking at the deltas and the shiftKey
of the event.
The only caveat is holding Ctrl key while swiping on the trackpad results in an actual scroll, but the ctrlKey
value of the event is true
in the same way as when the trackpad is pinched. So we can additionally listen for keydown/keyup on Ctrl to determine if Ctrl was really pressed while pinching or whether ctrlKey
was set to true
automatically due to pinching the trackpad.
Here's a working example:
// TRY IT
// document.addEventListener("wheel", (e) =>
// console.log(getWheelType(e), getWheelDirection(e)),
// );
// --------------------
const WHEEL_TYPES = {
TRACK_ZOOM: "TRACK_ZOOM",
TRACK_SCROLL: "TRACK_SCROLL",
MOUSE_ZOOM: "MOUSE_ZOOM",
MOUSE_SCROLL: "MOUSE_SCROLL",
};
const DIRECTIONS = {
UP: "UP",
DOWN: "DOWN",
LEFT: "LEFT",
RIGHT: "RIGHT",
IN: "IN",
OUT: "OUT",
};
const getWheelType = (event) => {
if (!(event instanceof WheelEvent)) {
throw "Event must be a WheelEvent";
}
if (isWheelZoom(event)) {
if (isWheelMouse(event)) {
return WHEEL_TYPES.MOUSE_ZOOM;
}
return WHEEL_TYPES.TRACK_ZOOM;
}
// Not a zoom, so must be a scroll
if (isWheelMouse(event)) {
return WHEEL_TYPES.MOUSE_SCROLL;
}
return WHEEL_TYPES.TRACK_SCROLL;
};
const getWheelDirection = (event) => {
if (!(event instanceof WheelEvent)) {
throw "Event must be a WheelEvent";
}
const maxDelta =
Math.abs(event.deltaX) > Math.abs(event.deltaY)
? event.deltaX
: event.deltaY;
if (event.ctrlKey && (isWheelMouse(event) || !isCtrlKeyPressed)) {
// it's a zoom
return getDeltaZoomDirection(maxDelta);
}
if (event.shiftKey) {
// Holding Shift while turning wheel or swiping trackpad in any direction
// results sideways scrolls (OS dependent of course, but seems to be the
// case on most).
//
// So we assume that if Shift was held, that it's a horizontal scroll.
return getMaxDeltaScrollDirection(maxDelta, 0);
} else {
// Otherwise, take the larger of the two deltas as indicating direction
return getMaxDeltaScrollDirection(event.deltaX, event.deltaY);
}
};
// --------------------
let isCtrlKeyPressed = false;
const onPress = (e) => {
if (e.key === "Control") {
isCtrlKeyPressed = true;
document.removeEventListener("keydown", onPress);
document.addEventListener("keyup", onDepress);
}
};
const onDepress = (e) => {
if (e.key === "Control") {
isCtrlKeyPressed = false;
document.addEventListener("keydown", onPress);
document.removeEventListener("keyup", onDepress);
}
};
// NOTE this only works if the page is focused
document.addEventListener("keydown", onPress);
const isWheelMouse = (event) => {
if (!(event instanceof WheelEvent)) {
throw "Event must be a WheelEvent";
}
// If exactly one of deltaX or deltaY is non-0,
// and is greater than 50, it's very likely a mouse wheel.
// Otherwise assume a trackpad.
if (
(event.deltaX === 0) !== (event.deltaY === 0) &&
Math.abs(event.deltaX + event.deltaY) > 50
) {
return true;
}
return false;
};
const isWheelZoom = (event) => {
if (!(event instanceof WheelEvent)) {
throw "Event must be a WheelEvent";
}
// If ctrlKey is set, then it's a zoom: either pinching trackpad or holding
// Ctrl while turning mouse wheel.
return event.ctrlKey === true;
};
const getMaxDeltaScrollDirection = (deltaX, deltaY) => {
if (deltaX === deltaY) {
return null;
}
if (Math.abs(deltaX) > Math.abs(deltaY)) {
return deltaX < 0 ? DIRECTIONS.LEFT : DIRECTIONS.RIGHT;
}
return deltaY < 0 ? DIRECTIONS.UP : DIRECTIONS.DOWN;
};
const getDeltaZoomDirection = (delta) => {
if (delta === 0) {
return null;
}
return delta < 0 ? DIRECTIONS.IN : DIRECTIONS.OUT;
};
Edit: this code was further refined and became part of a library I released, which among other things can handle gestures (scroll, zoom, drag) by one or more devices (key, wheel, touch, pointer).
First, you have to be careful when designing more advanced touch interactions: when the user uses a mouse it will respond via a click event, but when the user touches the screen both touch and click events will occur. For a single click the order of events is:
1) touchstart 2) touchmove 3) touchend 4) mouseover 5) mousemove 6) mousedown 7) mouseup 8) click
This, of course, means that if you are processing touch events like touchstart, you need to make sure that you don’t process the corresponding mousedown and/or click event as well. If you can cancel the touch events (call preventDefault() inside the event handler), then no mouse events will get generated for touch.
Update: You can identify touch or click like this: `
$('#element-id').on('click touchend',function(e){
if(e.type=='click')
console.log('Mouse Click');
else
console.log('Touch');
});
`
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745358956a4624272.html
评论列表(0条)