-
-
Save ucavus/5418463 to your computer and use it in GitHub Desktop.
Detect shake gestures in Cordova (Phonegap).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@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 ofHis 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 my6
in dimensionx
and-6
in dimensiony
will result in a nett movement of0
.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.