Accelerometer

Next, let's set up Kilo to duplicate the last entry in the list by shaking the phone. Add the following function to the end of kilo.js:

function dupeEntryById(entryId) { if (entryId == undefined) {

alert('You have to have at least one entry in the list to shake a dupe.'); } else {

db.transaction(©

function(transaction) { transaction.executeSql(

'INSERT INTO entries (date, food, calories, latitude, longitude) ' + 0 'SELECT date, food, calories, latitude, longitude ' + 'FROM entries WHERE id = ?;', [entryld], function() { refreshEntries();

}, errorHandlerO

O This line makes sure an entryld was passed to the function. If not, the user is notified. © Begin the usual database transaction steps.

© Define an INSERT statement that copies the values from the specified entryld. This is a type of query you haven't seen before. Instead of using a list of values for the INSERT, this takes the values from the results of a SELECT query for the specified entryId.

O Pass the entryId into the prepared statement, replacing the ? in the SELECT query with the value of the entryId.

© On success, call refreshEntries(), which will display the newly copied entry.

© On error, call the standard SQL error handler.

Now we need to tell the application when to start and stop watching the accelerometer. We'll set it up to start watching when the Date panel finishes sliding into view and to stop listening when the panel starts sliding out. To do this, we just need to add the following lines to the document ready function in kilo.js:

$('#date').bind('pageAnimationEnd', function(e, info){ if (info.direction == 'in') { startWatchingShake();

$('#date').bind('pageAnimationStart', function(e, info){ if (info.direction == 'out') { stopWatchingShake();

O Bind an anonymous handler to the pageAnimationEnd event of the #date panel. Pass the event and the additional information in as parameters.

© Check to see if the direction property of the info object equals in. If it does, call the startWatchingShake() function, which we'll look at shortly.

© Bind an anonymous handler to the pageAnimationBegin event of the #date panel. Pass the event and the additional information in as parameters.

O Check to see if the direction property of the info object equals out. If it does, call the stopWatchingShake() function, which we'll look at shortly.

Technically, we can bind to just one of the page animation events, like so:

$(l#date').bind('pageAnimationEndl, function(e, info){ if (info.direction == 'in') {

startWatchingShake(); } else {

stopWatchingShake();

The reason I didn't do this is that stopWatchingShake() will not be called until after the page animation is complete. Therefore, the accelerometer will be actively watched during the page transition, which can sometimes result in choppy animation.

All that's left for us to do is write the startWatchingShake() and stopWatchingShake() functions. Add the following functions to the end of kilo.js:

function startWatchingShake() { var success = function(coords){ var max = 2;

if (Math.abs(coords.x) > max || Math.abs(coords.y) > max || Math.abs(coords.z) > max) {

var entryld = $('#date ul li:last').data('entryId'); dupeEntryByld(entryld);©

var error = function(){}; var options = {}; options.frequency = 100; sessionStorage.watchId = navigator.accelerometer.watchAcceleration(success, error, options);©

function stopWatchingShake() {

navigator.accelerometer.clearWatch(sessionStorage.watchld);

O Begin the startWatchingShake() function. This function will be called when the #date panel finishes animating into view.

© Begin defining the success handler. It accepts a coordinates object as its sole parameter.

© Define the threshold for the shake. The higher the number, the harder the user will have to shake.

O Check to see if any of the coordinates have exceeded the threshold.

© Get the entryId of the last entry on the #date panel.

© Call the dupeEntryById() function.

O Define an empty error handler.

© Define an options object to pass in to the watchAcceleration() method of the accelerometer object.

© Set the frequency property of the options object to the number of milliseconds delay between receiving data from the accelerometer.

© Call the watchAcceleration() method of the accelerometer object, passing in the success handler, the error handler, and the options object as parameters. Store the result in sessionStorage.watchId, which we'll need for the stopWatchingShake() function.

© Begin the stopWatchingShake() function. This function will be called when the #date panel starts animating out of view.

© Call the clearWatch() method of the accelerometer object, passing it the watchId from session storage.

0 0

Post a comment