forked from processing-js/processing-js
-
Notifications
You must be signed in to change notification settings - Fork 1
/
processing-phonegap.js
executable file
·395 lines (333 loc) · 10.6 KB
/
processing-phonegap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
/*****************************************************
Processing PhoneGap Device API for Processing.js
[ http://docs.phonegap.com/en/1.1.0/index.html ]
This library exposes the PhoneGap API (1.1.0) to Processing code and
transforms callback and other JavaScript type constructs into Processing
friendly versions.
To Use:
<!doctype html>
<head>
<!-- Depends on Processing.js being loaded, and loaded first. -->
<script src="processing.js"></script>
<script src="processing-phonegap.js"></script>
</head>
...
</html>
NOTE: Create your processing instance with code so that you can wait for
the deviceready event, afterwhich you should listen for DOMContentLoaded.
New Processing types, constants methods, callbacks
--------------------------------------------------
// These are the currently unexposed apects of PhoneGap API. All of these
// can still be accessed via pure JavaScript calls. See the PhoneGap API docs.
// TODO:
// Camera
// Capture
// Contacts
// File
// Media
// Storage
// Device Strings via global device object
class Device {
String name;
String phonegap;
String platform;
String uuid;
Sevice version;
}
Device device;
// Acceleration type, global variable, and callback
class Acceleration {
float x;
float y;
float z;
Date timestamp;
}
Acceleration acceleration
// Accelerometer Event callback
void accelerometer() {
// acceleration is ready to be used
}
// Geolocation types, global variable, and callback
class Coords {
float latitude; // Latitude in decimal degrees.
float longitude; // Longitude in decimal degrees.
float altitude; // Height of the position in meters above the ellipsoid.
float accuracy; // Accuracy level of the latitude and longitude coordinates in meters.
float altitudeAccuracy; // Accuracy level of the altitude coordinate in meters.
float heading; // Direction of travel, specified in degrees counting clockwise relative to the true north.
float speed; // Current ground speed of the device, specified in meters per second.
}
class Position {
Coords coords; // The coords of the current position.
Date timestamp; // The timestamp of the current position.
}
Position position;
// Geolocation Event callback
void geolocation() {
// position is ready to be used
}
// Compass
class Heading {
float magneticHeading; // The heading in degrees from 0 - 359.99 at a single moment in time.
float trueHeading; // The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time.
float headingAccuracy; // headingAccuracy: The deviation in degrees between the reported heading and the true heading.
Date timestamp; // The time (ms) at which this heading was determined.
}
Heading heading;
// Compass Event Callback
void compass() {
// heading is ready to be used
}
// New Global Constants for Connection Type
UNKNOWN
ETHERNET
WIFI
CELL_2G
CELL_3G
CELL_4G
NONE
// Current Device Connection Type (one of the constants
// listed above)
object connectionType
// Processing's online variable is mapped to PhoneGap's
// event state for online/offline)
boolean online;
// Device Back Button Event Callback
void backButtonPressed() {
}
// Device Menu Button Event Callback
void menuButtonPressed() {
}
// Device Search Button Event Callback
void searchButtonPressed() {
}
// Device Start Call Button Event Callback
void startCallButtonPressed() {
}
// Device Start Call Button Event Callback
void endCallButtonPressed() {
}
// Device Volume Down Button Event Callback
void volumeDownButtonPressed() {
}
// Device Volume Up Button Event Callback
void volumeUpButtonPressed() {
}
// Beep method causes the device to beep the desired number of times.
beep(int num);
// Vibrate method causes the device to vibrate for the desired
// number of ms
vibrate(int ms);
*****************************************************/
(function(Processing, window, navigator, device) {
// Make sure we have Processing
if (!window.Processing) {
throw "Processing.js PhoneGap Error: Processing not loaded.";
}
// Make sure we're running on PhoneGap
if (!(window.device && window.device.phonegap)) {
throw "Processing.js PhoneGap Error: PhoneGap device API not found.";
}
// PhoneGap device state
var phoneGap = {
// The global device object
device: device,
// Whether or not the device is connected to the Internet
online: false,
// If we don't have support for acceleration events, use -1 for these.
acceleration: {
x: -1,
y: -1,
z: -1,
timestamp: Date.now()
},
// If we don't have support for compass events, use -1 for these.
heading: {
magneticHeading: -1,
trueHeading: -1,
headingAccuracy: -1,
timestamp: Date.now()
},
// Defaults for geolocation data
position: {
coords: {
latitude: 0,
longitude: 0,
accuracy: 0,
altitude: 0,
altitudeAccuracy: 0,
heading: -1,
speed: -1
},
timestamp: Date.now()
},
};
// Cache Processing ctor, prototype since we'll wrap/alter them.
var P5 = Processing,
Pp = Processing.prototype,
log = (console && console.log) ? console.log : function(){};
// Expose connection type constants via PConstants
var PConstants = Pp.PConstants;
PConstants.UNKNOWN = Connection.UNKNOWN;
PConstants.ETHERNET = Connection.ETHERNET;
PConstants.WIFI = Connection.WIFI;
PConstants.CELL_2G = Connection.CELL_2G;
PConstants.CELL_3G = Connection.CELL_3G;
PConstants.CELL_4G = Connection.CELL_4G;
PConstants.NONE = Connection.NONE;
// Expose connection type (shared for all instances)
Pp.__defineGetter__('connectionType', function() {
return navigator.network.connection.type;
});
// Expose beep method
Pp.beep = function(n) {
n = n || 1;
navigator.notification.beep(n);
}
// Expose vibrate method
Pp.vibrate = function(ms) {
ms = ms || 1000;
navigator.notification.vibrate(ms);
}
// Extend the Processing ctor.
window.Processing = function() {
var p5 = P5.apply(this, arguments),
aWatchID,
cWatchID,
gWatchID;
// Do we have an accelerometer callback? If so, start a watch
if (p5.accelerometer) {
aWatchID = navigator.accelerometer.watchAcceleration(
function(acceleration) {
phoneGap.acceleration = acceleration;
p5.accelerometer();
},
function() {
log('Processing.js PhoneGap Error: Unable to get accelerometer data.');
}
);
}
// Do we have a compass callback? If so, start a watch
if (p5.compass) {
cWatchID = navigator.compass.watchHeading(
function(heading) {
phoneGap.heading = heading;
p5.compass();
},
function() {
log('Processing.js PhoneGap Error: Unable to get compass data.');
}
);
}
// Do we have a geolocation callback? If so, start a watch
if (p5.geolocation) {
gWatchId = navigator.geolocation.watchPosition(
function(position) {
phoneGap.position = position;
p5.geolocation();
},
function() {
log('Processing.js PhoneGap Error: Unable to get geolocation data.');
}
);
}
// Do we have a startCallButtonPressed callback?
if (p5.startCallButtonPressed) {
document.addEventListener("startcallbutton", function() {
p5.startCallButtonPressed();
}, false);
}
// Do we have an endCallButtonPressed callback?
if (p5.endCallButtonPressed) {
document.addEventListener("endcallbutton", function() {
p5.endCallButtonPressed();
}, false);
}
// Do we have a searchButtonPressed callback?
if (p5.searchButtonPressed) {
document.addEventListener("searchbutton", function() {
p5.searchButtonPressed();
}, false);
}
// Do we have a backButtonPressed callback?
if (p5.backButtonPressed) {
document.addEventListener("backbutton", function() {
p5.backButtonPressed();
}, false);
}
// Do we have a menuButtonPressed callback?
if (p5.menuButtonPressed) {
document.addEventListener("menubutton", function() {
p5.menuButtonPressed();
}, false);
}
// Do we have a volumeDownButtonPressed callback?
if (p5.volumeDownButtonPressed) {
document.addEventListener("volumedownbutton", function() {
p5.volumeDownButtonPressed();
}, false);
}
// Do we have a volumeUpButtonPressed callback?
if (p5.volumeUpButtonPressed) {
document.addEventListener("volumeupbutton", function() {
p5.volumeUpButtonPressed();
}, false);
}
// When the app gets paused/resumed (put into background)
// stop/start our draw loop
document.addEventListener('pause', function() {
p5.noLoop();
}, false);
document.addEventListener('resume', function() {
p5.loop();
}, false);
// When the device's network state changes (connection to
// the Internet), change the value of Processing's online variable
document.addEventListener('online', function() {
phoneGap.online = true;
}, false);
document.addEventListener('offline', function() {
phoneGap.online = false;
}, false);
// Need to override the instance's default 'online' getter
delete p5.online;
p5.__defineGetter__('online', function() {
return phoneGap.online;
});
// Grab a reference to the existing exit method so we can extend it.
var exitFunc = p5.exit;
p5.exit = function() {
// Kill any running watches
if (aWatchID) {
navigator.accelerometer.clearWatch(aWatchID);
aWatchID = null;
}
if (cWatchID) {
navigator.compass.clearWatch(cWatchID);
cWatchID = null;
}
if (gWatchID) {
navigator.geolocation.clearWatch(gWatchID);
gWatchID = null;
}
// TODO: should clean up all the listeners we've attached...
// Do a proper clean-up using the original exit() method
exitFunc.apply(p5);
};
return p5;
};
window.Processing.prototype = Pp;
// Copy static properties onto the wrapped Processing
for (var prop in P5) {
if (!P5.hasOwnProperty(prop)) {
continue;
}
window.Processing[prop] = P5[prop];
}
// Attach the rest of the new global variables
['acceleration', 'heading', 'position'].forEach(function(objName) {
Pp.__defineGetter__(objName, function() {
return phoneGap[objName];
});
});
}(Processing, window, window.navigator, window.device));