-
-
Save ucavus/5418463 to your computer and use it in GitHub Desktop.
/* | |
The only required option is the "success" callback. Usage: | |
var shake = new Shake({ | |
frequency: 300, //milliseconds between polls for accelerometer data. | |
waitBetweenShakes: 1000, //milliseconds to wait before watching for more shake events. | |
threshold: 12, //how hard the shake has to be to register. | |
success: function(magnitude, accelerationDelta, timestamp) {}, //callback when shake is detected. "this" will be the "shake" object. | |
failure: function() {}, //callback when watching/getting acceleration fails. "this" will be the "shake" object. | |
}); | |
shake.startWatch(); | |
shake.stopWatch(); | |
*/ | |
function Shake(options) { | |
var shake = this, | |
watchId = null, | |
defaultOptions = { | |
frequency: 300, | |
waitBetweenShakes: 1000, | |
threshold: 12, | |
success: undefined, | |
failure: undefined | |
}, | |
previousAcceleration; | |
for (var p in defaultOptions) | |
if (!options.hasOwnProperty(p)) | |
options[p] = defaultOptions[p]; | |
// Start watching the accelerometer for a shake gesture | |
shake.startWatch = function () { | |
if (watchId) | |
return; | |
watchId = navigator.accelerometer.watchAcceleration(getAccelerationSnapshot, handleError, { | |
frequency: options.frequency | |
}); | |
}; | |
// Stop watching the accelerometer for a shake gesture | |
shake.stopWatch = function () { | |
if (!watchId) | |
return; | |
navigator.accelerometer.clearWatch(watchId); | |
watchId = null; | |
}; | |
// Gets the current acceleration snapshot from the last accelerometer watch | |
function getAccelerationSnapshot() { | |
navigator.accelerometer.getCurrentAcceleration(assessCurrentAcceleration, handleError); | |
} | |
// Assess the current acceleration parameters to determine a shake | |
function assessCurrentAcceleration(acceleration) { | |
if (!previousAcceleration) { | |
previousAcceleration = acceleration; | |
return; | |
} | |
var accelerationDelta = { | |
x: acceleration.x - previousAcceleration.x, | |
y: acceleration.y - previousAcceleration.y, | |
z: acceleration.z - previousAcceleration.z | |
}; | |
var magnitude = Math.sqrt( | |
Math.pow(accelerationDelta.x, 2) + | |
Math.pow(accelerationDelta.y, 2) + | |
Math.pow(accelerationDelta.z, 2) | |
); | |
if (magnitude >= options.threshold) { | |
// Shake detected | |
if (options.waitBetweenShakes > 0) { | |
shake.stopWatch(); | |
previousAcceleration = undefined; | |
} | |
options.success.call(shake, magnitude, accelerationDelta, acceleration.timestamp); | |
if (options.waitBetweenShakes > 0) | |
setTimeout( | |
function() { | |
shake.startWatch(); | |
}, | |
options.waitBetweenShakes | |
); | |
} | |
else | |
previousAcceleration = acceleration; | |
} | |
// Handle errors here | |
function handleError() { | |
if (options.failure) | |
options.failure.call(shake); | |
} | |
}; |
Do you mind providing a working HTML-file for this? I cant get it to work!
I´ve tried
shake.startWatch(myFunction());
wich fires upon start, but when I shake the phone, nothing happens!
My index.php:
<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
?>
<!DOCTYPE HTML>
<html lang="sv-SE">
<head>
<title>Test</title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
<link href="styles.css?<?php echo time(); ?>" rel="stylesheet" type="text/css">
<script type="text/javascript" src="shake.js?<?php echo time(); ?>"></script>
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// Cordova is ready
//
function onDeviceReady() {
var element = document.getElementById('deviceProperties');
element.innerHTML = 'Device Name: ' + device.name + '<br />' +
'Device Cordova: ' + device.cordova + '<br />' +
'Device Platform: ' + device.platform + '<br />' +
'Device UUID: ' + device.uuid + '<br />' +
'Device Model: ' + device.model + '<br />' +
'Device Version: ' + device.version + '<br />';
var shake = new Shake({
frequency: 300, //milliseconds between polls for accelerometer data.
waitBetweenShakes: 1000, //milliseconds to wait before watching for more shake events.
threshold: 12, //how hard the shake has to be to register.
success: function(magnitude, accelerationDelta, timestamp) {}, //callback when shake is detected. "this" will be the "shake" object.
failure: function() {}, //callback when watching/getting acceleration fails. "this" will be the "shake" object.
});
shake.startWatch();
shake.stopWatch(myFunction() );
function myFunction(){
alert("test");
}
}
</script>
</head>
<body>
<div><p id="deviceProperties">Loading device properties...</p></div>
<!-- javascrtipt for later use -->
<script type="text/javascript" src="jquery-1.9.1.js?<?php echo time(); ?>"></script>
<script type="text/javascript" src="iscroll.js?<?php echo time(); ?>"></script>
<script type="text/javascript" src="scroll.js?<?php echo time(); ?>"></script>
<script type="text/javascript" src="cordova-2.7.0.js?<?php echo time(); ?>"></script>
<!--<script type="text/javascript" src="shake.js?<?php echo time(); ?>"></script>-->
</body>
</html>
dannythunder, because you called "shake.stopWatch" after you start it.
As a heads-up, neither this nor the original seem to be compatible with iOS 8. :'(
(at least I'm guessing that's the weakest link on my end)
hey @ucavus and @rubencodes can you confirm if/how this is now broken in os 8+?
nm.. works with ios8.
All the fixes proposed by this plugin have been addressed by the original author, @leecrossley. See https://github.com/leecrossley/cordova-plugin-shake-detection
@dandv Not so. The main issue that prompted me to fork in the first place is still not right. Lee apparently does not know how to get a 3d vector's magnitude. In his code, a move of His does not provide any way to use the error handling function without modifying the plugin. It will also fire shake events continuously which is not what I wanted (see my 6
in dimension x
and -6
in dimension y
will result in a nett movement of 0
.waitBetweenShakes
option). It's nice that it's been Cordova-ised, but I wouldn't use it.
Edit: I was wrong about the nett movement bit, but it's still not getting the magnitude correctly. I'm just not a fan of that shake detection logic.
I had a few issues with the original:
Math.abs()
only takes one argument.)