I'm attempting to use Pointer Events to detect graphics tablet input including pen pressure, but Chrome and Firefox don't seem to be reading the tablet device (Wacom Intuos 4) properly. All pointer events come back with the same pointerId and pointerType as my mouse, with the default pressure reading of 0.5. The code I'm using looks something like this:
container.addEventListener("pointerdown", (event) => {
console.log(event.pointerId);
console.log(event.pointerType);
console.log(event.pressure);
}, true);
This outputs "1", "mouse", and "0.5". This occurs for the "pointerdown", "pointermove", and "pointerup" events.
I've tried this on both Windows and Linux with the appropriate drivers installed, and other applications detect pen pressure (Krita, for instance).
Do Chrome and Firefox not support graphics tablets properly yet, or am I simply doing something wrong?
To answer your question:
Do Chrome and Firefox not support graphics tablets properly yet, or am I simply doing something wrong?
No, you're not doing anything wrong.
Most modern browsers support Pointer Events. I have found that (like everything else browser based) the degree of "support" can vary.
This begs the quesiton, "how do we avoid the browser incompatibility nonsense?" For this particular case, I'd recommend Pressure.js.
To see it in action (and test it with your device of choice), check out the Pressure.js examples.
Try using a function like below to determine if the different pointer types are being detected:
targetElement.addEventListener("pointerdown", function(ev) {
// Call the appropriate pointer type handler
switch (ev.pointerType) {
case "mouse":
process_pointer_mouse(ev);
break;
case "pen":
process_pointer_pen(ev);
break;
case "touch":
process_pointer_touch(ev);
break;
default:
console.log("pointerType " + ev.pointerType + " is Not suported");
}
}, false);
Mozilla has lots of documentation on pointer events for mouse, pens, and touch.
https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events
https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/pointerType
You might get better results if you enable/disable Windows Ink and/or add the following CSS for your element.
div {
touch-action: none;
}
I use this code for that it can open div boxes and shadows on div boxes when you slide over it.
if (!("ontouch" in document.documentElement)) {
document.documentElement.className += " no-touch";
}
$('html').on('touch touchend', function(e) {
$(this).toggleClass('over');
});
But I noticed that on a samsung galaxy 5 it doesn't work as good as on an iphone.
When using an iphone it just works on sliding over it. BUT on an android on windows touch phone you really have to press it a little to have the same effect. Is there a way to fix this?
You can test it on my webste https://www.gester.nl if you have both phones.
Thanks for the answers in advance.
Greetings from Holland.
jQuery takes care of most cross browser problems like this - you have it so use it.. Also, you might mean ontouchstart rather than ontouch.
if (!("ontouchstart" in document.documentElement)) {
$(document.documentElement).addClass("no-touch");
}
$('html').on('touch touchend', function(e) {
$(this).toggleClass('over');
});
Hi, particulary I am having a problem with HighCharts / HighStock not scrolling on the x-axis to display hidden data such as the times contained here:
It works just fine in Chrome browser on my Desktop. Whenever I scroll the overthrow-polyfill.js error shows itself. This is not a library I included myself as I can't find any mention of overthrow in all my code.
Sidenote: I do have angular touch and fastclick in the mix as well, but removing them did not help either
I've got the same problem on mobile device. After couple of hour i have found that scrolling is available just on mousemove event, but not on touch event. To fix this I have added the same listeners on touch events.
Highcharts.Pointer.prototype.onContainerTouchStart = Highcharts.Pointer.prototype.onContainerMouseDown;
var onContainerMouseMove = Highcharts.Pointer.prototype.onContainerMouseMove;
Highcharts.Pointer.prototype.onContainerTouchMove = function(e) {
onContainerMouseMove.call(this, e);
if ("touchstart" === this.chart.mouseIsDown) {
this.drag(e);
}
};
I'm just a lowly uC programmer who's trying to put together a little web interface for his boss. I've got everything working so far except being able to select a square on a canvas using touch input.
This is on a Samsung Slate 7 tablet running Windows 8 and IE10
I've distilled the code down to pretty much the bare essentials here:
var cxt;
var c;
window.onload = function () {
c = document.getElementById('displayCanvas');
cxt = c.getContext('2d');
/*
c.addEventListener("MSPointerUp", mouseUp, false);
c.addEventListener("MSPointerMove", mouseMove, false);
c.addEventListener("MSPointerDown", mouseDown, false);
*/
c.addEventListener("touchend", mouseUp, false)
c.addEventListener("touchmove", mouseMove, false);
c.addEventListener("touchstart", mouseDown, false);
}
function mouseDown(downE) {
window.console && console.log("down");
};
function mouseMove(moveE){
window.console && console.log("move");
}
function mouseUp() {
window.console && console.log("end");
}
I get both the start and end events, using both the MSPointer and the "normal" javascript touch events, however the "move" event doesn't register.
I'm sure it's something really simple I'm missing here, thanks for helping me out!
I'm assuming you are interacting with the HTML page in desktop IE on Windows 8. In desktop IE, the MSPointerMove is not firing on that canvas because the default behavior when the user moves their finger around on the screen is to pan the content. If you style the canvas with the following snippet your MSPointerMove event should be detected.
style="-ms-touch-action: none"
Here's a great article on how to get touch working on many browsers. http://blogs.msdn.com/b/ie/archive/2011/10/19/handling-multi-touch-and-mouse-input-in-all-browsers.aspx
The Samsung Slate 7 tablets have a bug in older versions of the drivers that might be relevant. I saw another answer tagged [internet-explorer-10] that had the details. Have you updated your driver?
In Javascript/jQuery, how can I detect if the client device has a mouse?
I've got a site that slides up a little info panel when the user hovers their mouse over an item. I'm using jQuery.hoverIntent to detect the hover, but this obviously doesn't work on touchscreen devices like iPhone/iPad/Android. So on those devices I'd like to revert to tap to show the info panel.
var isTouchDevice = 'ontouchstart' in document.documentElement;
Note: Just because a device supports touch events doesn't necessarily mean that it is exclusively a touch screen device. Many devices (such as my Asus Zenbook) support both click and touch events, even when they doen't have any actual touch input mechanisms. When designing for touch support, always include click event support and never assume any device is exclusively one or the other.
Found testing for window.Touch didn't work on android but this does:
function is_touch_device() {
return !!('ontouchstart' in window);
}
See article: What's the best way to detect a 'touch screen' device using JavaScript?
+1 for doing hover and click both. One other way could be using CSS media queries and using some styles only for smaller screens / mobile devices, which are the ones most likely to have touch / tap functionality. So if you have some specific styles via CSS, and from jQuery you check those elements for the mobile device style properties you could hook into them to write you mobile specific code.
See here: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
isTouch = true;
} else {
isTouch = false;
}
Works every where !!
return (('ontouchstart' in window)
|| (navigator.maxTouchPoints > 0)
|| (navigator.msMaxTouchPoints > 0));
Reason for using maxTouchPoints alongwith msMaxTouchPoints:
Microsoft has stated that starting with Internet Explorer 11,
Microsoft vendor prefixed version of this property (msMaxTouchPoints)
may be removed and recommends using maxTouchPoints instead.
Source : http://ctrlq.org/code/19616-detect-touch-screen-javascript
I use:
if(jQuery.support.touch){
alert('Touch enabled');
}
in jQuery mobile 1.0.1
Google Chrome seems to return false positives on this one:
var isTouch = 'ontouchstart' in document.documentElement;
I suppose it has something to do with its ability to "emulate touch events" (F12 -> settings at lower right corner -> "overrides" tab -> last checkbox). I know it's turned off by default but that's what I connect the change in results with (the "in" method used to work in Chrome).
However, this seems to be working, as far as I have tested:
var isTouch = !!("undefined" != typeof document.documentElement.ontouchstart);
All browsers I've run that code on state the typeof is "object" but I feel more certain knowing that it's whatever but undefined :-)
Tested on IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome for iPad 21.0.1180.80 and iPad Safari. It would be cool if someone made some more tests and shared the results.
Wrote this for one of my sites and probably is the most foolproof solution. Especially since even Modernizr can get false positives on touch detection.
If you're using jQuery
$(window).one({
mouseover : function(){
Modernizr.touch = false; // Add this line if you have Modernizr
$('html').removeClass('touch').addClass('mouse');
}
});
or just pure JS...
window.onmouseover = function(){
window.onmouseover = null;
document.getElementsByTagName("html")[0].className += " mouse";
}
For my first post/comment:
We all know that 'touchstart' is triggered before click.
We also know that when user open your page he or she will:
1) move the mouse
2) click
3) touch the screen (for scrolling, or ... :) )
Let's try something :
//--> Start: jQuery
var hasTouchCapabilities = 'ontouchstart' in window && (navigator.maxTouchPoints || navigator.msMaxTouchPoints);
var isTouchDevice = hasTouchCapabilities ? 'maybe':'nope';
//attach a once called event handler to window
$(window).one('touchstart mousemove click',function(e){
if ( isTouchDevice === 'maybe' && e.type === 'touchstart' )
isTouchDevice = 'yes';
});
//<-- End: jQuery
Have a nice day!
I have tested following code mentioned above in the discussion
function is_touch_device() {
return !!('ontouchstart' in window);
}
works on android Mozilla, chrome, Opera, android default browser and safari on iphone...
all positive ...
seems solid for me :)
A helpful blog post on the subject, linked to from within the Modernizr source for detecting touch events. Conclusion: it's not possible to reliably detect touchscreen devices from Javascript.
http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
This works for me:
function isTouchDevice(){
return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
If you use Modernizr, it is very easy to use Modernizr.touch as mentioned earlier.
However, I prefer using a combination of Modernizr.touch and user agent testing, just to be safe.
var deviceAgent = navigator.userAgent.toLowerCase();
var isTouchDevice = Modernizr.touch ||
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/) ||
deviceAgent.match(/(iemobile)/) ||
deviceAgent.match(/iphone/i) ||
deviceAgent.match(/ipad/i) ||
deviceAgent.match(/ipod/i) ||
deviceAgent.match(/blackberry/i) ||
deviceAgent.match(/bada/i));
if (isTouchDevice) {
//Do something touchy
} else {
//Can't touch this
}
If you don't use Modernizr, you can simply replace the Modernizr.touch function above with ('ontouchstart' in document.documentElement)
Also note that testing the user agent iemobile will give you broader range of detected Microsoft mobile devices than Windows Phone.
Also see this SO question
In jQuery Mobile you can simply do:
$.support.touch
Don't know why this is so undocumented.. but it is crossbrowser safe (latest 2 versions of current browsers).
As already mentioned, a device may support both mouse and touch input. Very often, the question is not "what is supported" but "what is currently used".
For this case, you can simply register mouse events (including the hover listener) and touch events alike.
element.addEventListener('touchstart',onTouchStartCallback,false);
element.addEventListener('onmousedown',onMouseDownCallback,false);
...
JavaScript should automatically call the correct listener based on user input. So, in case of a touch event, onTouchStartCallback will be fired, emulating your hover code.
Note that a touch may fire both kinds of listeners, touch and mouse. However, the touch listener goes first and can prevent subsequent mouse listeners from firing by calling event.preventDefault().
function onTouchStartCallback(ev) {
// Call preventDefault() to prevent any further handling
ev.preventDefault();
your code...
}
Further reading here.
For iPad development I am using:
if (window.Touch)
{
alert("touchy touchy");
}
else
{
alert("no touchy touchy");
}
I can then selectively bind to the touch based events (eg ontouchstart) or mouse based events (eg onmousedown). I haven't yet tested on android.