Why doesn't paper.js path creation work on iOS devices? - javascript

** See Edit 2 for the current solution to this issue. **
I have a somewhat obscure issue that Google and searching through StackOverflow hasn't solved yet. Paper.js isn't working through iOS.
Currently I'm building a whiteboard drawing web-app that utilizes paper.js for the drawing functionality. It's working just fine on the desktop in Chrome, FireFox, and Safari. On Android devices it works fine, but is quite laggy. The problem crops up when using the app on iOS devices.
For some reason it is not possible for my app to create paths when using it on iOS through mobile Safari or mobile Chrome. The behavior on iOS is just a non-responsive canvas.
I currently don't have access to a device that I can use for remote debugging, so I am not able to gather any useful debugging data.
Web app link for testing.
http://alexpersian.github.io/html/whiteboard.html
Code snippet of paperscript involved in drawing.
var myPath;
function onMouseDown(event) {
myPath = new Path();
myPath.add(event.point);
myPath.strokeColor = WBAPP.penColor; // WBAPP is from main Javascript
myPath.strokeWidth = WBAPP.penStroke;
myPath.strokeCap = 'round';
}
function onMouseDrag(event) {
myPath.add(event.point);
}
function onMouseUp(event) {
myPath.simplify();
}
Edit: I've completed some further testing and found that it works on devices running iOS 7, but not iOS 8. I'm curious if there was a change to iOS 8 that limited touchEvents web interaction.
Edit 2: I was able to solve this issue by adding this snippet of code.
document.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
This prevents the default touch action on iOS 8, which seems to be a scroll/pan action, because it interferes with the onMouseDrag event from paper.js.
Jürg Lehni, paper.js co-creator, is looking into whether this should be included in the library itself. Until then, this snippet should help.

Hey probably you will need to implement touch events you can use
http://labs.rampinteractive.co.uk/touchSwipe/demos/ to do that
or
http://www.homeandlearn.co.uk/JS/html5_canvas_touch_events.html

Related

A-Frame look-controls very unstable on older devices

I'm building a 360 panorama viewer with A-Frame 1.0.4 and I'm having some trouble with older devices that I don't know how to solve. I'm testing in a WebView inside an Android application.
On most recent devices, the gyroscope and accelerometer work great, but on older devices (for example ASUS X008D), it's all shaky, the view can't stay still when I put the phone on the table or when I hold it. I thought it could be due to polyfills but I can't figure how. I added some logs to check for DeviceMotionEvent and DeviceOrientationEvent and both are recognized but it seems like it's not enough.
How could I be sure that the events are handled correctly and eventually disable the hmd in look-controls manually when it's not stable enough? There would still be the dragging and I would be fine with that.
Thanks for your help :)
After further investigations I found out where the issue came from. It was because the Sensor API was not available on some devices and the Gyroscope wasn't read correctly. If I understood correctly there was a fallback on DeviceMotion but it was probably not good on older devices, I don't know...
What I did to "fix" this was writing this little snippet to check that the Gyroscope class was available. If it was not I disabled all movements from look-controls component to allow only manual movements. I hope it can help anyone who meets this issue. It's kinda quick'n'dirty but it did the job so I'm okay with this.
var gyroscope = null;
try {
gyroscope = new Gyroscope();
gyroscope.addEventListener('error', event => {
document.getElementById("camera").setAttribute("look-controls", "magicWindowTrackingEnabled: false");
});
gyroscope.start();
// Stop the gyroscope after trying so it does not run in background.
setTimeout(function() { gyroscope.stop(); }, 500);
} catch (error) {
document.getElementById("camera").setAttribute("look-controls", "magicWindowTrackingEnabled: false");
}
There's also an open issue about it on A-Frame github page.

How can I address the Samsung Android browser?

I'm working on a responsive website and I have a weird CSS/JS issue with the default touchwiz browser of Android Samsung devices. I've searched on StackOverflow, finding some unhelpful answers like this.
I have the physical devices to test on, but since it's not possible to do remote debugging on these browsers it's really time consuming to make changes, deploy them a QA server, test, and retry.
Any idea on how can I speed up my testing or targeting that specific browsers?
Useragent is not helping in my case...
Just to make an example: one of the many problems I'm facing is on this free component, it's not positioning in the middle of the screen, while it's ok on all other android and iOS browsers.
For mobile testing, here are some resources might help.
Personally I prefer the Samsung emulator and Adobe Edge Inspect(will charge).
Adobe Edge Inspect
Samsung Emulators
Chrome - Device Mode & Mobile Emulation (recommended only for testing responsiveness)
Keynote (might charge fee)
Because the limit of the content length, Please click the links and see the detailed documentation.
Hope it will help to speed up the testing and debug on mobile devices.
If you have a device I would suggest you to try this tool weinre
It's allow you to remote debug. I always use it for stuff like that
JSBin can take care of the JS debug. Combined with the CSSRule API and the following to grab the browser's default style values for an element and its current rendered values, you might be able to get somewhere.
function defaultStyle(tag) {
var defaultStyles = {},
testElem = document.createElement(tag),
getStyle = 'getComputedStyle' in window,
styles;
document.body.appendChild(testElem);
styles = (getStyle) ? window.getComputedStyle(testElem) : testElem.currentStyle;
for (var prop in styles) {
if (!(/^\d+$/.test(prop))) {
defaultStyles[prop] = styles[prop];
}
}
document.body.removeChild(testElem);
return defaultStyles;
}
function currentStyle(elem) {
var currentStyles = {},
getStyle = 'getComputedStyle' in window,
styles;
styles = (getStyle) ? window.getComputedStyle(elem) : elem.currentStyle;
for (var prop in styles) {
if (!(/^\d+$/.test(prop))) {
currentStyles[prop] = styles[prop];
}
}
document.body.removeChild(testElem);
return currentStyles;
}
Use media queries for making css based on screen lengths. It does not matter whether it is samsung or iphone browser. You can also use bootstrap libraries for it.

Phonegap canvas not drawing on android but works fine in browser

I've made a simple HTML5 noughts and crosses(tic tac toe) game that uses the canvas element and I am trying to use phonegap to get it working on Android. I've test it works fine on firefox, chrome and internet explorer but when I get built using phonegap the apk produced simply renders a white screen.
I've tried using the ripple emulator and it renders and behaves as expected fine. Really confused as to why its not working.
To work on pc instead of phoengap you have to change
document.addEventListener("deviceready",onDeviceReady, false);
to
document.addEventListener("DOMContentLoaded",onDeviceReady, false);
in main.js.
I am using fast-canvas as a plugin, see the config file.
Code is avaliable here as well as assets here: https://github.com/JacobRawling/XandOs
Please help I am very confused and am struggling to find any phonegap tutorials that use
canvas.
Thanks very much
Your solution is jqscribble – A touch enabled canvas drawing tool
http://plugins.jquery.com/jqscribble/

Can I use Javascript to get the compass heading for iOS and Android?

Can I use Javascript in a cross-platform way to get the compass heading in iOS and Android (with Chrome), without using something like PhoneGap? I know iOS has DeviceOrientationEvent, but I can't find any equivalent on Chrome for Android.
As a primer you should review this previous related StackOverflow answer and be familiar with the general practical considerations for using DeviceOrientation Events in web applications.
The simple solution I provided in my previous related StackOverflow answer only applies to browsers that implement absolute deviceorientation events (i.e. browsers where the deviceorientation alpha property is compass-oriented). That means the solution provided there currently only works in Android browsers and not iOS-based browsers or any other browser that does not provide absolute-based deviceorientation event data.
To reliably obtain the current compass heading across both Android and iOS browsers today you need to handle both absolute and non-absolute implementations that provide the additional webkitCompassHeading property and make sure to account for any current screen orientation changes as part of that. AFAIK the only library that currently does this is Full Tilt JS (disclaimer: I am the author of this library).
The following code will give you the same correct compass heading across both iOS and Android browsers, taking account of the differences in device orientation implementations and applying any necessary runtime screen orientation transforms too:
<!-- Include the Full Tilt JS library from https://github.com/richtr/Full-Tilt-JS -->
<script src="fulltilt-min.js"></script>
<script>
// Obtain a new *world-oriented* Full Tilt JS DeviceOrientation Promise
var promise = FULLTILT.getDeviceOrientation({ 'type': 'world' });
// Wait for Promise result
promise.then(function(deviceOrientation) { // Device Orientation Events are supported
// Register a callback to run every time a new
// deviceorientation event is fired by the browser.
deviceOrientation.listen(function() {
// Get the current *screen-adjusted* device orientation angles
var currentOrientation = deviceOrientation.getScreenAdjustedEuler();
// Calculate the current compass heading that the user is 'looking at' (in degrees)
var compassHeading = 360 - currentOrientation.alpha;
// Do something with `compassHeading` here...
});
}).catch(function(errorMessage) { // Device Orientation Events are not supported
console.log(errorMessage);
// Implement some fallback controls here...
});
</script>
Here is a demo that demonstrates this technique to obtain the compass heading the user is facing. It should work well on both iOS and Android browsers.
The implementation of the code in that demo is as shown above and can be viewed on Github at ./scripts/compass.js:L268-L272.
Yes you can! Unfortunately the alpha doesn't work on iPhones/iPads. With Mobile Safari, alpha is based on the direction the device was pointing when device orientation was first requested. The included webkit offers you the compass heading. To make it work for all other browsers (which all supports alpha as compassheading) you can use the following Javascript code:
if (window.DeviceOrientationEvent) {
// Listen for the deviceorientation event and handle the raw data
window.addEventListener('deviceorientation', function(eventData) {
var compassdir;
if(event.webkitCompassHeading) {
// Apple works only with this, alpha doesn't work
compassdir = event.webkitCompassHeading;
}
else compassdir = event.alpha;
});
}
Android also supports Webkit, so would also use event.webkitCompassHeading, but that's OK.
BTW: "oncompassneedscalibration" is also not supported for iPhones and iPads.
I believe you can use the "heading" field of the location object, from navigator.geolocation, please see here:
https://developer.mozilla.org/en-US/docs/WebAPI/Using_geolocation
I know no other way.
Hope it helps,
A.

AppCache excruciatingly slow on iOS

I am developing a web-app utilizing Application Cache, and everything is working great on desktop browsers and on Android (even very old & slow android handsets). However downloading the appcache is taking much much much longer on iOS 6 in both Safari and Chrome.
My application cache total size is a mere 2.1Mb, and I have a pretty solid 70Mbps (download) internet connection. I would expect caching to be pretty rapid.
Here are my times so far:
Desktop Chrome: <1s (similar times for Safari & Firefox)
Android 2.3.3 Stock Browser: ~4s (similar times for Chrome & Dolphin)
Android 4.2.2 (Emulated): ~7s (running inside a PhoneGap app)
iPhone 4S 6.0 Safari: 8 minutes!!! (around the same in iOS Chrome too!!)
iPad 2 6.0 Safari: as above!!!
All of these devices are using the same wifi and internet connection, and my iPhone/iPad are otherwise functioning fine (no native apps exhibiting internet speed issues, and regular websites load just fine). There just seems to be something absolutely decimating AppCache download speed under iOS.
The window.applicationCache.status throughout this time is appCache.DOWNLOADING, and I have a progress event running counting the files as they are downloaded, so I'm certain that it is not stuck elsewhere. This just appears to be the time it takes to download. What gives?
Addendum : The iPhone also runs ridiculously hot, and the battery ticks down very quickly during this operation. It seems that something is causing the CPU to run flat-out during this download.
(Note: I can't publish a link to the web-app here as we're still in private beta, but if you would need to see it before you think you'd be able to help diagnose it, email me at the address in my profile and I'll send a link to the app).
Okay, I figured it out with the help of the iOS Emulator, and Xcode Instruments to profile it. (I'm not sure if I should add my solution into the main question, or as an answer, but I thought I'd do it this way as my question is already a little cluttered).
As it turns out, it was actually some erroneous javascript causing the issue, but apparently only on iOS.
The web-app is intended to only be a single page high (no vertical scrolling, except within specific DIVs), so in addition to the usual standard JS code for hiding the address bar...
window.addEventListener("load",function() {
// Set a timeout...
setTimeout(function(){
// Hide the address bar!
window.scrollTo(0, 1);
}, 0);
});
...I had also added in the following:
$(document).scroll(
function(e){
window.scrollTo(0, 1);
});
From looking at the profile results, I was able to see that a lot of time was being spent in scrollTo, so it immediately pointed to this as the cause. Why the scroll event was being triggered so much, I have no idea (this was occurring with no touching of the screen whatsoever).
My initial fix is to throttle that code, but I am now evaluating whether or not I even need it at all. Here is the code I have that fixes it for now (using jquery-debounce, which I was already using for something else):
$(document).scroll(
$.throttle(function(e){
window.scrollTo(0, 1);
})
, 10);
The download time of the application cache is now in line with the Android times. Phew!
The code is getting itself into an infinite loop, as the initial scrollTo function call triggers the scroll event handler, which then repeatedly re-triggers itself! My best guess is that the iOS JavaScript engine handles this infinite loop differently to the other browsers' JavaScript engines.

Categories

Resources