melonjs 11.0.0 → 13.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +6 -6
- package/dist/melonjs.js +22854 -22604
- package/dist/melonjs.min.js +5 -6
- package/dist/melonjs.module.d.ts +289 -284
- package/dist/melonjs.module.js +22427 -22175
- package/package.json +16 -16
- package/src/application/application.js +231 -0
- package/src/audio/audio.js +13 -7
- package/src/camera/camera2d.js +6 -6
- package/src/game.js +9 -232
- package/src/index.js +3 -3
- package/src/input/keyboard.js +2 -2
- package/src/input/pointer.js +4 -5
- package/src/input/pointerevent.js +10 -10
- package/src/lang/deprecated.js +27 -30
- package/src/level/level.js +2 -2
- package/src/level/tiled/TMXGroup.js +10 -0
- package/src/level/tiled/TMXLayer.js +11 -2
- package/src/level/tiled/TMXObject.js +13 -2
- package/src/level/tiled/TMXTileMap.js +15 -3
- package/src/level/tiled/TMXTileset.js +8 -0
- package/src/loader/loader.js +64 -28
- package/src/loader/loadingscreen.js +28 -115
- package/src/loader/melonjs_logo.png +0 -0
- package/src/math/color.js +62 -42
- package/src/math/observable_vector2.js +26 -2
- package/src/math/observable_vector3.js +32 -4
- package/src/math/vector2.js +23 -0
- package/src/math/vector3.js +26 -0
- package/src/physics/body.js +27 -51
- package/src/physics/detector.js +3 -3
- package/src/physics/quadtree.js +58 -29
- package/src/physics/world.js +32 -3
- package/src/polyfill/index.js +4 -0
- package/src/renderable/container.js +2 -2
- package/src/renderable/imagelayer.js +8 -8
- package/src/renderable/nineslicesprite.js +27 -1
- package/src/renderable/trigger.js +4 -4
- package/src/state/stage.js +1 -1
- package/src/state/state.js +50 -3
- package/src/system/device.js +814 -981
- package/src/system/event.js +2 -1
- package/src/system/platform.js +32 -0
- package/src/system/save.js +23 -14
- package/src/system/timer.js +12 -35
- package/src/text/bitmaptext.js +1 -2
- package/src/text/text.js +10 -14
- package/src/text/textmetrics.js +1 -2
- package/src/tweens/tween.js +6 -6
- package/src/utils/string.js +13 -24
- package/src/video/canvas/canvas_renderer.js +30 -65
- package/src/video/renderer.js +23 -30
- package/src/video/texture/canvas_texture.js +39 -3
- package/src/video/video.js +27 -25
- package/src/video/webgl/glshader.js +1 -1
- package/src/video/webgl/webgl_compositor.js +2 -2
- package/src/video/webgl/webgl_renderer.js +8 -20
package/src/system/device.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { hasAudio } from "./../audio/audio.js";
|
|
2
1
|
import { getParent } from "./../video/video.js";
|
|
3
2
|
import save from "./save.js";
|
|
4
3
|
import { prefixed } from "./../utils/agent.js";
|
|
5
|
-
import state from "./../state/state.js";
|
|
6
|
-
import * as event from "./event.js";
|
|
7
4
|
import { DOMContentLoaded } from "./dom.js";
|
|
5
|
+
import * as device_platform from "./platform.js"; // export * as name1 from …; // ECMAScript® 2020
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* device type and capabilities
|
|
9
|
+
* @namespace device
|
|
10
|
+
*/
|
|
8
11
|
|
|
9
|
-
// private properties
|
|
10
12
|
let accelInitialized = false;
|
|
11
13
|
let deviceOrientationInitialized = false;
|
|
12
|
-
|
|
13
14
|
// swipe utility fn & flag
|
|
14
15
|
let swipeEnabled = true;
|
|
16
|
+
// a cache DOMRect object
|
|
17
|
+
let domRect = {left: 0, top: 0, x: 0, y: 0, width: 0, height: 0, right: 0, bottom: 0};
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
* @ignore
|
|
18
|
-
*/
|
|
19
|
-
function _disableSwipeFn(e) {
|
|
19
|
+
function disableSwipeFn(e) {
|
|
20
20
|
e.preventDefault();
|
|
21
21
|
if (typeof globalThis.scroll === "function") {
|
|
22
22
|
globalThis.scroll(0, 0);
|
|
@@ -24,1044 +24,877 @@ function _disableSwipeFn(e) {
|
|
|
24
24
|
return false;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
function hasLocalStorage() {
|
|
28
|
+
try {
|
|
29
|
+
return !!globalThis.localStorage;
|
|
30
|
+
} catch (e) {
|
|
31
|
+
// the above generates an exception when cookies are blocked
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function hasOffscreenCanvas() {
|
|
37
|
+
try {
|
|
38
|
+
// some browser (e.g. Safari) implements WebGL1 and WebGL2 contexts only
|
|
39
|
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=801176
|
|
40
|
+
return (typeof globalThis.OffscreenCanvas !== "undefined") && ((new globalThis.OffscreenCanvas(0, 0).getContext( "2d" )) !== null);
|
|
41
|
+
} catch (e) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
29
45
|
|
|
30
46
|
/**
|
|
31
|
-
*
|
|
32
|
-
* @ignore
|
|
47
|
+
* used by [un]watchAccelerometer()
|
|
33
48
|
*/
|
|
34
|
-
function
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
device.android2 = /Android 2/i.test(device.ua);
|
|
40
|
-
// Linux platform
|
|
41
|
-
device.linux = /Linux/i.test(device.ua);
|
|
42
|
-
// Chrome OS ?
|
|
43
|
-
device.chromeOS = /CrOS/.test(device.ua);
|
|
44
|
-
// Windows Device ?
|
|
45
|
-
device.wp = /Windows Phone/i.test(device.ua);
|
|
46
|
-
// Blackberry device ?
|
|
47
|
-
device.BlackBerry = /BlackBerry/i.test(device.ua);
|
|
48
|
-
// Kindle device ?
|
|
49
|
-
device.Kindle = /Kindle|Silk.*Mobile Safari/i.test(device.ua);
|
|
50
|
-
// Mobile platform
|
|
51
|
-
device.isMobile = /Mobi/i.test(device.ua) ||
|
|
52
|
-
device.iOS ||
|
|
53
|
-
device.android ||
|
|
54
|
-
device.wp ||
|
|
55
|
-
device.BlackBerry ||
|
|
56
|
-
device.Kindle || false;
|
|
57
|
-
// ejecta
|
|
58
|
-
device.ejecta = (typeof globalThis.ejecta !== "undefined");
|
|
59
|
-
// Wechat
|
|
60
|
-
device.isWeixin = /MicroMessenger/i.test(device.ua);
|
|
49
|
+
function onDeviceMotion(e) {
|
|
50
|
+
// Accelerometer information
|
|
51
|
+
accelerationX = e.accelerationIncludingGravity.x;
|
|
52
|
+
accelerationY = e.accelerationIncludingGravity.y;
|
|
53
|
+
accelerationZ = e.accelerationIncludingGravity.z;
|
|
61
54
|
};
|
|
62
55
|
|
|
63
56
|
/**
|
|
64
|
-
*
|
|
65
|
-
* @ignore
|
|
57
|
+
* used by [un]watchDeviceOrientation()
|
|
66
58
|
*/
|
|
67
|
-
function
|
|
59
|
+
export function onDeviceRotate(e) {
|
|
60
|
+
gamma = e.gamma;
|
|
61
|
+
beta = e.beta;
|
|
62
|
+
alpha = e.alpha;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* the device platform type
|
|
67
|
+
* @name platform
|
|
68
|
+
* @memberof device
|
|
69
|
+
* @readonly
|
|
70
|
+
* @public
|
|
71
|
+
* @type {device.platform}
|
|
72
|
+
*/
|
|
73
|
+
export let platform = device_platform;
|
|
68
74
|
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
/**
|
|
76
|
+
* True if the browser supports Touch Events
|
|
77
|
+
* @name touchEvent
|
|
78
|
+
* @memberof device
|
|
79
|
+
* @type {boolean}
|
|
80
|
+
* @readonly
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
export const touchEvent = !!("ontouchstart" in globalThis);
|
|
71
84
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
/**
|
|
86
|
+
* True if the browser supports Pointer Events
|
|
87
|
+
* @name pointerEvent
|
|
88
|
+
* @memberof device
|
|
89
|
+
* @type {boolean}
|
|
90
|
+
* @readonly
|
|
91
|
+
* @public
|
|
92
|
+
*/
|
|
93
|
+
export const pointerEvent = !!globalThis.PointerEvent;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Touch capabilities (support either Touch or Pointer events)
|
|
97
|
+
* @name touch
|
|
98
|
+
* @memberof device
|
|
99
|
+
* @type {boolean}
|
|
100
|
+
* @readonly
|
|
101
|
+
* @public
|
|
102
|
+
*/
|
|
103
|
+
export const touch = touchEvent || pointerEvent;
|
|
76
104
|
|
|
77
|
-
|
|
78
|
-
|
|
105
|
+
/**
|
|
106
|
+
* the maximum number of simultaneous touch contact points are supported by the current device.
|
|
107
|
+
* @name maxTouchPoints
|
|
108
|
+
* @memberof device
|
|
109
|
+
* @type {number}
|
|
110
|
+
* @readonly
|
|
111
|
+
* @public
|
|
112
|
+
* @example
|
|
113
|
+
* if (me.device.maxTouchPoints > 1) {
|
|
114
|
+
* // device supports multi-touch
|
|
115
|
+
* }
|
|
116
|
+
*/
|
|
117
|
+
export const maxTouchPoints = touch ? (pointerEvent ? globalThis.navigator.maxTouchPoints || 1 : 10) : 1;
|
|
79
118
|
|
|
80
|
-
|
|
81
|
-
|
|
119
|
+
/**
|
|
120
|
+
* W3C standard wheel events
|
|
121
|
+
* @name wheel
|
|
122
|
+
* @memberof device
|
|
123
|
+
* @type {boolean}
|
|
124
|
+
* @readonly
|
|
125
|
+
* @public
|
|
126
|
+
*/
|
|
127
|
+
export const wheel = typeof globalThis.document !== "undefined" && "onwheel" in globalThis.document.createElement("div");
|
|
82
128
|
|
|
83
|
-
// detect wheel event support
|
|
84
|
-
// Modern browsers support "wheel", Webkit and IE support at least "mousewheel
|
|
85
|
-
device.wheel = typeof globalThis.document !== "undefined" && "onwheel" in globalThis.document.createElement("div");
|
|
86
129
|
|
|
87
|
-
|
|
88
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Browser pointerlock api support
|
|
132
|
+
* @name hasPointerLockSupport
|
|
133
|
+
* @memberof device
|
|
134
|
+
* @type {boolean}
|
|
135
|
+
* @readonly
|
|
136
|
+
* @public
|
|
137
|
+
*/
|
|
138
|
+
export const hasPointerLockSupport = typeof globalThis.document !== "undefined" && typeof globalThis.document.pointerLockElement !== "undefined";
|
|
89
139
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Browser device orientation
|
|
142
|
+
* @name hasDeviceOrientation
|
|
143
|
+
* @memberof device
|
|
144
|
+
* @readonly
|
|
145
|
+
* @public
|
|
146
|
+
* @type {boolean}
|
|
147
|
+
*/
|
|
148
|
+
export const hasDeviceOrientation = !!globalThis.DeviceOrientationEvent;
|
|
93
149
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Supports the ScreenOrientation API
|
|
152
|
+
* @name screenOrientation
|
|
153
|
+
* @memberof device
|
|
154
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation/onchange
|
|
155
|
+
* @type {boolean}
|
|
156
|
+
* @readonly
|
|
157
|
+
* @public
|
|
158
|
+
*/
|
|
159
|
+
export const screenOrientation = (typeof screen !== "undefined") && (typeof screen.orientation !== "undefined");
|
|
97
160
|
|
|
98
|
-
|
|
99
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Browser accelerometer capabilities
|
|
163
|
+
* @name hasAccelerometer
|
|
164
|
+
* @memberof device
|
|
165
|
+
* @readonly
|
|
166
|
+
* @public
|
|
167
|
+
* @type {boolean}
|
|
168
|
+
*/
|
|
169
|
+
export const hasAccelerometer = !!globalThis.DeviceMotionEvent;
|
|
100
170
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Browser full screen support
|
|
173
|
+
* @name hasFullscreenSupport
|
|
174
|
+
* @memberof device
|
|
175
|
+
* @type {boolean}
|
|
176
|
+
* @readonly
|
|
177
|
+
* @public
|
|
178
|
+
*/
|
|
179
|
+
export const hasFullscreenSupport = typeof globalThis.document !== "undefined" && (prefixed("fullscreenEnabled", globalThis.document) || globalThis.document.mozFullScreenEnabled);
|
|
104
180
|
|
|
181
|
+
if (hasFullscreenSupport === true) {
|
|
182
|
+
globalThis.document.exitFullscreen = prefixed("cancelFullScreen", globalThis.document) || prefixed("exitFullscreen", globalThis.document);
|
|
183
|
+
}
|
|
105
184
|
|
|
106
|
-
|
|
107
|
-
|
|
185
|
+
/**
|
|
186
|
+
* Device WebAudio Support
|
|
187
|
+
* @name hasWebAudio
|
|
188
|
+
* @memberof device
|
|
189
|
+
* @type {boolean}
|
|
190
|
+
* @readonly
|
|
191
|
+
* @public
|
|
192
|
+
*/
|
|
193
|
+
export const hasWebAudio = !!(globalThis.AudioContext || globalThis.webkitAudioContext);
|
|
108
194
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Device HTML5Audio Support
|
|
197
|
+
* @name hasHTML5Audio
|
|
198
|
+
* @memberof device
|
|
199
|
+
* @type {boolean}
|
|
200
|
+
* @readonly
|
|
201
|
+
* @public
|
|
202
|
+
*/
|
|
203
|
+
export const hasHTML5Audio = (typeof globalThis.Audio !== "undefined");
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Returns true if the browser/device has audio capabilities.
|
|
207
|
+
* @name sound
|
|
208
|
+
* @memberof device
|
|
209
|
+
* @type {boolean}
|
|
210
|
+
* @readonly
|
|
211
|
+
* @public
|
|
212
|
+
*/
|
|
213
|
+
export const sound = hasWebAudio || hasHTML5Audio;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Browser Local Storage capabilities <br>
|
|
217
|
+
* (this flag will be set to false if cookies are blocked)
|
|
218
|
+
* @name localStorage
|
|
219
|
+
* @memberof device
|
|
220
|
+
* @readonly
|
|
221
|
+
* @public
|
|
222
|
+
* @type {boolean}
|
|
223
|
+
*/
|
|
224
|
+
export const localStorage = hasLocalStorage();
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* equals to true if the device browser supports OffScreenCanvas.
|
|
228
|
+
* @name offscreenCanvas
|
|
229
|
+
* @memberof device
|
|
230
|
+
* @type {boolean}
|
|
231
|
+
* @readonly
|
|
232
|
+
* @public
|
|
233
|
+
*/
|
|
234
|
+
export const offscreenCanvas = hasOffscreenCanvas();
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Browser Base64 decoding capability
|
|
238
|
+
* @name nativeBase64
|
|
239
|
+
* @memberof device
|
|
240
|
+
* @type {boolean}
|
|
241
|
+
* @readonly
|
|
242
|
+
* @public
|
|
243
|
+
*/
|
|
244
|
+
export const nativeBase64 = (typeof(globalThis.atob) === "function");
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* a string representing the preferred language of the user, usually the language of the browser UI.
|
|
248
|
+
* (will default to "en" if the information is not available)
|
|
249
|
+
* @name language
|
|
250
|
+
* @memberof device
|
|
251
|
+
* @type {string}
|
|
252
|
+
* @readonly
|
|
253
|
+
* @public
|
|
254
|
+
* @see http://www.w3schools.com/tags/ref_language_codes.asp
|
|
255
|
+
*/
|
|
256
|
+
export const language = typeof globalThis.navigator !== "undefined" ? globalThis.navigator.language || globalThis.navigator.browserLanguage || globalThis.navigator.userLanguage || "en" : "en";
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Ratio of the resolution in physical pixels to the resolution in CSS pixels for the current display device.
|
|
260
|
+
* @name devicePixelRatio
|
|
261
|
+
* @memberof device
|
|
262
|
+
* @type {number}
|
|
263
|
+
* @readonly
|
|
264
|
+
* @public
|
|
265
|
+
*/
|
|
266
|
+
export const devicePixelRatio = globalThis.devicePixelRatio || 1;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* equals to true if a mobile device.
|
|
270
|
+
* (Android | iPhone | iPad | iPod | BlackBerry | Windows Phone | Kindle)
|
|
271
|
+
* @name isMobile
|
|
272
|
+
* @memberof device
|
|
273
|
+
* @type {boolean}
|
|
274
|
+
* @readonly
|
|
275
|
+
* @public
|
|
276
|
+
*/
|
|
277
|
+
export const isMobile = platform.isMobile;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* contains the g-force acceleration along the x-axis.
|
|
281
|
+
* @name accelerationX
|
|
282
|
+
* @memberof device
|
|
283
|
+
* @type {number}
|
|
284
|
+
* @readonly
|
|
285
|
+
* @public
|
|
286
|
+
* @see device.watchAccelerometer
|
|
287
|
+
*/
|
|
288
|
+
export let accelerationX = 0;
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* contains the g-force acceleration along the y-axis.
|
|
292
|
+
* @name accelerationY
|
|
293
|
+
* @memberof device
|
|
294
|
+
* @type {number}
|
|
295
|
+
* @readonly
|
|
296
|
+
* @public
|
|
297
|
+
* @see device.watchAccelerometer
|
|
298
|
+
*/
|
|
299
|
+
export let accelerationY = 0;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* contains the g-force acceleration along the z-axis.
|
|
303
|
+
* @name accelerationZ
|
|
304
|
+
* @memberof device
|
|
305
|
+
* @type {number}
|
|
306
|
+
* @readonly
|
|
307
|
+
* @public
|
|
308
|
+
* @see device.watchAccelerometer
|
|
309
|
+
*/
|
|
310
|
+
export let accelerationZ = 0;
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Device orientation Gamma property. Gives angle on tilting a portrait held phone left or right
|
|
314
|
+
* @name gamma
|
|
315
|
+
* @memberof device
|
|
316
|
+
* @type {number}
|
|
317
|
+
* @readonly
|
|
318
|
+
* @public
|
|
319
|
+
* @see device.watchDeviceOrientation
|
|
320
|
+
*/
|
|
321
|
+
export let gamma = 0;
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Device orientation Beta property. Gives angle on tilting a portrait held phone forward or backward
|
|
325
|
+
* @name beta
|
|
326
|
+
* @memberof device
|
|
327
|
+
* @type {number}
|
|
328
|
+
* @readonly
|
|
329
|
+
* @public
|
|
330
|
+
* @see device.watchDeviceOrientation
|
|
331
|
+
*/
|
|
332
|
+
export let beta = 0;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Device orientation Alpha property. Gives angle based on the rotation of the phone around its z axis.
|
|
336
|
+
* The z-axis is perpendicular to the phone, facing out from the center of the screen.
|
|
337
|
+
* @name alpha
|
|
338
|
+
* @memberof device
|
|
339
|
+
* @type {number}
|
|
340
|
+
* @readonly
|
|
341
|
+
* @public
|
|
342
|
+
* @see device.watchDeviceOrientation
|
|
343
|
+
*/
|
|
344
|
+
export let alpha = 0;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Specify whether to pause the game when losing focus
|
|
348
|
+
* @name pauseOnBlur
|
|
349
|
+
* @memberof device
|
|
350
|
+
* @type {boolean}
|
|
351
|
+
* @public
|
|
352
|
+
* @default true
|
|
353
|
+
*/
|
|
354
|
+
export let pauseOnBlur = true;
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Specify whether to unpause the game when gaining focus
|
|
358
|
+
* @name resumeOnFocus
|
|
359
|
+
* @memberof device
|
|
360
|
+
* @type {boolean}
|
|
361
|
+
* @public
|
|
362
|
+
* @default true
|
|
363
|
+
*/
|
|
364
|
+
export let resumeOnFocus = true;
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Specify whether to automatically bring the window to the front
|
|
368
|
+
* @name autoFocus
|
|
369
|
+
* @memberof device
|
|
370
|
+
* @type {boolean}
|
|
371
|
+
* @public
|
|
372
|
+
* @default true
|
|
373
|
+
*/
|
|
374
|
+
export let autoFocus = true;
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Specify whether to stop the game when losing focus or not.
|
|
378
|
+
* The engine restarts on focus if this is enabled.
|
|
379
|
+
* @name stopOnBlur
|
|
380
|
+
* @memberof device
|
|
381
|
+
* @type {boolean}
|
|
382
|
+
* @public
|
|
383
|
+
* @default false
|
|
384
|
+
*/
|
|
385
|
+
export let stopOnBlur = false;
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* specify a function to execute when the Device is fully loaded and ready
|
|
389
|
+
* @function onReady
|
|
390
|
+
* @memberof device
|
|
391
|
+
* @public
|
|
392
|
+
* @param {Function} fn the function to be executed
|
|
393
|
+
* @example
|
|
394
|
+
* // small game skeleton
|
|
395
|
+
* var game = {
|
|
396
|
+
* // called by the me.device.onReady function
|
|
397
|
+
* onload = function () {
|
|
398
|
+
* // init video
|
|
399
|
+
* if (!me.video.init('screen', 640, 480, true)) {
|
|
400
|
+
* alert("Sorry but your browser does not support html 5 canvas.");
|
|
401
|
+
* return;
|
|
402
|
+
* }
|
|
403
|
+
*
|
|
404
|
+
* // initialize the "audio"
|
|
405
|
+
* me.audio.init("mp3,ogg");
|
|
406
|
+
*
|
|
407
|
+
* // set callback for ressources loaded event
|
|
408
|
+
* me.loader.onload = this.loaded.bind(this);
|
|
409
|
+
*
|
|
410
|
+
* // set all ressources to be loaded
|
|
411
|
+
* me.loader.preload(game.assets);
|
|
412
|
+
*
|
|
413
|
+
* // load everything & display a loading screen
|
|
414
|
+
* me.state.change(me.state.LOADING);
|
|
415
|
+
* };
|
|
416
|
+
*
|
|
417
|
+
* // callback when everything is loaded
|
|
418
|
+
* loaded = function () {
|
|
419
|
+
* // define stuff
|
|
420
|
+
* // ....
|
|
421
|
+
*
|
|
422
|
+
* // change to the menu screen
|
|
423
|
+
* me.state.change(me.state.PLAY);
|
|
424
|
+
* }
|
|
425
|
+
* }; // game
|
|
426
|
+
*
|
|
427
|
+
* // "bootstrap"
|
|
428
|
+
* me.device.onReady(function () {
|
|
429
|
+
* game.onload();
|
|
430
|
+
* });
|
|
431
|
+
*/
|
|
432
|
+
export function onReady(fn) {
|
|
433
|
+
DOMContentLoaded(fn);
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* enable/disable swipe on WebView.
|
|
438
|
+
* @function enableSwipe
|
|
439
|
+
* @memberof device
|
|
440
|
+
* @public
|
|
441
|
+
* @param {boolean} [enable=true] enable or disable swipe.
|
|
442
|
+
*/
|
|
443
|
+
export function enableSwipe(enable) {
|
|
444
|
+
let moveEvent = pointerEvent ? "pointermove" : (touchEvent ? "touchmove" : "mousemove");
|
|
445
|
+
if (enable !== false) {
|
|
446
|
+
if (swipeEnabled === false) {
|
|
447
|
+
globalThis.document.removeEventListener(moveEvent, disableSwipeFn);
|
|
448
|
+
swipeEnabled = true;
|
|
449
|
+
}
|
|
450
|
+
} else if (swipeEnabled === true) {
|
|
451
|
+
globalThis.document.addEventListener(moveEvent, disableSwipeFn, { passive: false });
|
|
452
|
+
swipeEnabled = false;
|
|
114
453
|
}
|
|
454
|
+
};
|
|
115
455
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
456
|
+
/**
|
|
457
|
+
* Returns true if the browser/device is in full screen mode.
|
|
458
|
+
* @function isFullscreen
|
|
459
|
+
* @memberof device
|
|
460
|
+
* @public
|
|
461
|
+
* @returns {boolean}
|
|
462
|
+
*/
|
|
463
|
+
export function isFullscreen() {
|
|
464
|
+
if (hasFullscreenSupport) {
|
|
465
|
+
return !!(prefixed("fullscreenElement", document) || document.mozFullScreenElement);
|
|
466
|
+
} else {
|
|
467
|
+
return false;
|
|
124
468
|
}
|
|
469
|
+
};
|
|
125
470
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
471
|
+
/**
|
|
472
|
+
* Triggers a fullscreen request. Requires fullscreen support from the browser/device.
|
|
473
|
+
* @function requestFullscreen
|
|
474
|
+
* @memberof device
|
|
475
|
+
* @public
|
|
476
|
+
* @param {object} [element=default canvas object] the element to be set in full-screen mode.
|
|
477
|
+
* @example
|
|
478
|
+
* // add a keyboard shortcut to toggle Fullscreen mode on/off
|
|
479
|
+
* me.input.bindKey(me.input.KEY.F, "toggleFullscreen");
|
|
480
|
+
* me.event.on(me.event.KEYDOWN, function (action, keyCode, edge) {
|
|
481
|
+
* // toggle fullscreen on/off
|
|
482
|
+
* if (action === "toggleFullscreen") {
|
|
483
|
+
* me.device.requestFullscreen();
|
|
484
|
+
* } else {
|
|
485
|
+
* me.device.exitFullscreen();
|
|
486
|
+
* }
|
|
487
|
+
* });
|
|
488
|
+
*/
|
|
489
|
+
export function requestFullscreen(element) {
|
|
490
|
+
if (hasFullscreenSupport && !isFullscreen()) {
|
|
491
|
+
element = element || getParent();
|
|
492
|
+
element.requestFullscreen = prefixed("requestFullscreen", element) || element.mozRequestFullScreen;
|
|
493
|
+
element.requestFullscreen();
|
|
149
494
|
}
|
|
495
|
+
};
|
|
150
496
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
497
|
+
/**
|
|
498
|
+
* Exit fullscreen mode. Requires fullscreen support from the browser/device.
|
|
499
|
+
* @function exitFullscreen
|
|
500
|
+
* @memberof device
|
|
501
|
+
* @public
|
|
502
|
+
*/
|
|
503
|
+
export function exitFullscreen() {
|
|
504
|
+
if (hasFullscreenSupport && isFullscreen()) {
|
|
505
|
+
document.exitFullscreen();
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Return a string representing the orientation of the device screen.
|
|
511
|
+
* It can be "any", "natural", "landscape", "portrait", "portrait-primary", "portrait-secondary", "landscape-primary", "landscape-secondary"
|
|
512
|
+
* @function getScreenOrientation
|
|
513
|
+
* @memberof device
|
|
514
|
+
* @public
|
|
515
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Screen/orientation
|
|
516
|
+
* @returns {string} the screen orientation
|
|
517
|
+
*/
|
|
518
|
+
export function getScreenOrientation() {
|
|
519
|
+
const PORTRAIT = "portrait";
|
|
520
|
+
const LANDSCAPE = "landscape";
|
|
521
|
+
|
|
522
|
+
let screen = globalThis.screen;
|
|
523
|
+
|
|
524
|
+
// first try using "standard" values
|
|
525
|
+
if (screenOrientation === true) {
|
|
526
|
+
let orientation = prefixed("orientation", screen);
|
|
527
|
+
if (typeof orientation !== "undefined" && typeof orientation.type === "string") {
|
|
528
|
+
// Screen Orientation API specification
|
|
529
|
+
return orientation.type;
|
|
530
|
+
} else if (typeof orientation === "string") {
|
|
531
|
+
// moz/ms-orientation are strings
|
|
532
|
+
return orientation;
|
|
167
533
|
}
|
|
534
|
+
}
|
|
168
535
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
536
|
+
// check using the deprecated API
|
|
537
|
+
if (typeof globalThis.orientation === "number") {
|
|
538
|
+
return (Math.abs(globalThis.orientation) === 90) ? LANDSCAPE : PORTRAIT;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// fallback to window size check
|
|
542
|
+
return (globalThis.outerWidth > globalThis.outerHeight) ? LANDSCAPE : PORTRAIT;
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* locks the device screen into the specified orientation.<br>
|
|
547
|
+
* This method only works for installed Web apps or for Web pages in full-screen mode.
|
|
548
|
+
* @function lockOrientation
|
|
549
|
+
* @memberof device
|
|
550
|
+
* @public
|
|
551
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation
|
|
552
|
+
* @param {string|string[]} orientation The orientation into which to lock the screen.
|
|
553
|
+
* @returns {boolean} true if the orientation was unsuccessfully locked
|
|
554
|
+
*/
|
|
555
|
+
export function lockOrientation(orientation) {
|
|
556
|
+
let screen = globalThis.screen;
|
|
557
|
+
if (typeof screen !== "undefined") {
|
|
558
|
+
let _lockOrientation = prefixed("lockOrientation", screen);
|
|
559
|
+
if (typeof _lockOrientation !== "undefined") {
|
|
560
|
+
return _lockOrientation(orientation);
|
|
191
561
|
}
|
|
192
562
|
}
|
|
563
|
+
return false;
|
|
564
|
+
};
|
|
193
565
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
566
|
+
/**
|
|
567
|
+
* unlocks the device screen into the specified orientation.<br>
|
|
568
|
+
* This method only works for installed Web apps or for Web pages in full-screen mode.
|
|
569
|
+
* @function unlockOrientation
|
|
570
|
+
* @memberof device
|
|
571
|
+
* @public
|
|
572
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation
|
|
573
|
+
* @returns {boolean} true if the orientation was unsuccessfully unlocked
|
|
574
|
+
*/
|
|
575
|
+
export function unlockOrientation() {
|
|
576
|
+
let screen = globalThis.screen;
|
|
577
|
+
if (typeof screen !== "undefined") {
|
|
578
|
+
let _unlockOrientation = prefixed("unlockOrientation", screen);
|
|
579
|
+
if (typeof _unlockOrientation !== "undefined") {
|
|
580
|
+
return _unlockOrientation();
|
|
581
|
+
}
|
|
198
582
|
}
|
|
583
|
+
return false;
|
|
584
|
+
};
|
|
199
585
|
|
|
586
|
+
/**
|
|
587
|
+
* return true if the device screen orientation is in Portrait mode
|
|
588
|
+
* @function isPortrait
|
|
589
|
+
* @memberof device
|
|
590
|
+
* @public
|
|
591
|
+
* @returns {boolean}
|
|
592
|
+
*/
|
|
593
|
+
export function isPortrait() {
|
|
594
|
+
return getScreenOrientation().includes("portrait");
|
|
200
595
|
};
|
|
201
596
|
|
|
597
|
+
/**
|
|
598
|
+
* return true if the device screen orientation is in Portrait mode
|
|
599
|
+
* @function isLandscape
|
|
600
|
+
* @memberof device
|
|
601
|
+
* @public
|
|
602
|
+
* @returns {boolean}
|
|
603
|
+
*/
|
|
604
|
+
export function isLandscape() {
|
|
605
|
+
return getScreenOrientation().includes("landscape");
|
|
606
|
+
};
|
|
202
607
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
608
|
+
/**
|
|
609
|
+
* return the device storage
|
|
610
|
+
* @function getStorage
|
|
611
|
+
* @memberof device
|
|
612
|
+
* @public
|
|
613
|
+
* @see save
|
|
614
|
+
* @param {string} [type="local"]
|
|
615
|
+
* @returns {object} a reference to the device storage
|
|
616
|
+
*/
|
|
617
|
+
export function getStorage(type = "local") {
|
|
618
|
+
switch (type) {
|
|
619
|
+
case "local" :
|
|
620
|
+
return save;
|
|
207
621
|
|
|
622
|
+
default :
|
|
623
|
+
throw new Error("storage type " + type + " not supported");
|
|
624
|
+
}
|
|
625
|
+
};
|
|
208
626
|
|
|
209
|
-
// public export
|
|
210
627
|
/**
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* @
|
|
628
|
+
* return the parent DOM element for the given parent name or HTMLElement object
|
|
629
|
+
* @function getParentElement
|
|
630
|
+
* @memberof device
|
|
631
|
+
* @public
|
|
632
|
+
* @param {string|HTMLElement} element the parent element name or a HTMLElement object
|
|
633
|
+
* @returns {HTMLElement} the parent Element
|
|
214
634
|
*/
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* the `ua` read-only property returns the user agent string for the current browser.
|
|
219
|
-
* @type {string}
|
|
220
|
-
* @readonly
|
|
221
|
-
* @name ua
|
|
222
|
-
*/
|
|
223
|
-
ua : typeof globalThis.navigator !== "undefined" ? globalThis.navigator.userAgent : "",
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Browser Local Storage capabilities <br>
|
|
227
|
-
* (this flag will be set to false if cookies are blocked)
|
|
228
|
-
* @type {boolean}
|
|
229
|
-
* @readonly
|
|
230
|
-
* @name localStorage
|
|
231
|
-
*/
|
|
232
|
-
localStorage : false,
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Browser accelerometer capabilities
|
|
236
|
-
* @type {boolean}
|
|
237
|
-
* @readonly
|
|
238
|
-
* @name hasAccelerometer
|
|
239
|
-
*/
|
|
240
|
-
hasAccelerometer : false,
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Browser device orientation
|
|
244
|
-
* @type {boolean}
|
|
245
|
-
* @readonly
|
|
246
|
-
* @name hasDeviceOrientation
|
|
247
|
-
*/
|
|
248
|
-
hasDeviceOrientation : false,
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Supports the ScreenOrientation API
|
|
252
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation/onchange
|
|
253
|
-
* @type {boolean}
|
|
254
|
-
* @readonly
|
|
255
|
-
* @name ScreenOrientation
|
|
256
|
-
*/
|
|
257
|
-
ScreenOrientation : false,
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Browser full screen support
|
|
261
|
-
* @type {boolean}
|
|
262
|
-
* @readonly
|
|
263
|
-
* @name hasFullscreenSupport
|
|
264
|
-
*/
|
|
265
|
-
hasFullscreenSupport : false,
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Browser pointerlock api support
|
|
269
|
-
* @type {boolean}
|
|
270
|
-
* @readonly
|
|
271
|
-
* @name hasPointerLockSupport
|
|
272
|
-
*/
|
|
273
|
-
hasPointerLockSupport : false,
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Device WebAudio Support
|
|
277
|
-
* @type {boolean}
|
|
278
|
-
* @readonly
|
|
279
|
-
* @name hasWebAudio
|
|
280
|
-
*/
|
|
281
|
-
hasWebAudio : false,
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Browser Base64 decoding capability
|
|
285
|
-
* @type {boolean}
|
|
286
|
-
* @readonly
|
|
287
|
-
* @name nativeBase64
|
|
288
|
-
*/
|
|
289
|
-
nativeBase64 : (typeof(globalThis.atob) === "function"),
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Return the maximum number of simultaneous touch contact points are supported by the current device.
|
|
293
|
-
* @type {number}
|
|
294
|
-
* @readonly
|
|
295
|
-
* @name maxTouchPoints
|
|
296
|
-
* @example
|
|
297
|
-
* if (me.device.maxTouchPoints > 1) {
|
|
298
|
-
* // device supports multi-touch
|
|
299
|
-
* }
|
|
300
|
-
*/
|
|
301
|
-
maxTouchPoints : 1,
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Touch capabilities
|
|
305
|
-
* @type {boolean}
|
|
306
|
-
* @readonly
|
|
307
|
-
* @name touch
|
|
308
|
-
*/
|
|
309
|
-
touch : false,
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* W3C standard wheel events
|
|
313
|
-
* @type {boolean}
|
|
314
|
-
* @readonly
|
|
315
|
-
* @name wheel
|
|
316
|
-
*/
|
|
317
|
-
wheel : false,
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* equals to true if a mobile device <br>
|
|
321
|
-
* (Android | iPhone | iPad | iPod | BlackBerry | Windows Phone | Kindle)
|
|
322
|
-
* @type {boolean}
|
|
323
|
-
* @readonly
|
|
324
|
-
* @name isMobile
|
|
325
|
-
*/
|
|
326
|
-
isMobile : false,
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* equals to true if the device is an iOS platform.
|
|
330
|
-
* @type {boolean}
|
|
331
|
-
* @readonly
|
|
332
|
-
* @name iOS
|
|
333
|
-
*/
|
|
334
|
-
iOS : false,
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* equals to true if the device is an Android platform.
|
|
338
|
-
* @type {boolean}
|
|
339
|
-
* @readonly
|
|
340
|
-
* @name android
|
|
341
|
-
*/
|
|
342
|
-
android : false,
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* equals to true if the device is an Android 2.x platform.
|
|
346
|
-
* @type {boolean}
|
|
347
|
-
* @readonly
|
|
348
|
-
* @name android2
|
|
349
|
-
*/
|
|
350
|
-
android2 : false,
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* equals to true if the device is a Linux platform.
|
|
354
|
-
* @type {boolean}
|
|
355
|
-
* @readonly
|
|
356
|
-
* @name linux
|
|
357
|
-
*/
|
|
358
|
-
linux : false,
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* equals to true if the game is running under Ejecta.
|
|
362
|
-
* @type {boolean}
|
|
363
|
-
* @readonly
|
|
364
|
-
* @see http://impactjs.com/ejecta
|
|
365
|
-
* @name ejecta
|
|
366
|
-
*/
|
|
367
|
-
ejecta : false,
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* equals to true if the is running under Wechat.
|
|
371
|
-
* @type {boolean}
|
|
372
|
-
* @readonly
|
|
373
|
-
* @name isWeixin
|
|
374
|
-
*/
|
|
375
|
-
isWeixin : false,
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* equals to true if running under node.js
|
|
379
|
-
* @type {boolean}
|
|
380
|
-
* @readonly
|
|
381
|
-
* @name nodeJS
|
|
382
|
-
*/
|
|
383
|
-
nodeJS : (typeof globalThis.process !== "undefined") && (typeof globalThis.process.release !== "undefined") && (globalThis.process.release.name === "node"),
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* equals to true if the device is running on ChromeOS.
|
|
387
|
-
* @type {boolean}
|
|
388
|
-
* @readonly
|
|
389
|
-
* @name chromeOS
|
|
390
|
-
*/
|
|
391
|
-
chromeOS : false,
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* equals to true if the device is a Windows Phone platform.
|
|
395
|
-
* @type {boolean}
|
|
396
|
-
* @readonly
|
|
397
|
-
* @name wp
|
|
398
|
-
*/
|
|
399
|
-
wp : false,
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* equals to true if the device is a BlackBerry platform.
|
|
403
|
-
* @type {boolean}
|
|
404
|
-
* @readonly
|
|
405
|
-
* @name BlackBerry
|
|
406
|
-
*/
|
|
407
|
-
BlackBerry : false,
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* equals to true if the device is a Kindle platform.
|
|
411
|
-
* @type {boolean}
|
|
412
|
-
* @readonly
|
|
413
|
-
* @name Kindle
|
|
414
|
-
*/
|
|
415
|
-
Kindle : false,
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* contains the g-force acceleration along the x-axis.
|
|
419
|
-
* @public
|
|
420
|
-
* @type {number}
|
|
421
|
-
* @readonly
|
|
422
|
-
* @name accelerationX
|
|
423
|
-
* @see device.watchAccelerometer
|
|
424
|
-
*/
|
|
425
|
-
accelerationX : 0,
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
* contains the g-force acceleration along the y-axis.
|
|
429
|
-
* @public
|
|
430
|
-
* @type {number}
|
|
431
|
-
* @readonly
|
|
432
|
-
* @name accelerationY
|
|
433
|
-
* @see device.watchAccelerometer
|
|
434
|
-
*/
|
|
435
|
-
accelerationY : 0,
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* contains the g-force acceleration along the z-axis.
|
|
439
|
-
* @public
|
|
440
|
-
* @type {number}
|
|
441
|
-
* @readonly
|
|
442
|
-
* @name accelerationZ
|
|
443
|
-
* @see device.watchAccelerometer
|
|
444
|
-
*/
|
|
445
|
-
accelerationZ : 0,
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Device orientation Gamma property. Gives angle on tilting a portrait held phone left or right
|
|
449
|
-
* @public
|
|
450
|
-
* @type {number}
|
|
451
|
-
* @readonly
|
|
452
|
-
* @name gamma
|
|
453
|
-
* @see device.watchDeviceOrientation
|
|
454
|
-
*/
|
|
455
|
-
gamma : 0,
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* Device orientation Beta property. Gives angle on tilting a portrait held phone forward or backward
|
|
459
|
-
* @public
|
|
460
|
-
* @type {number}
|
|
461
|
-
* @readonly
|
|
462
|
-
* @name beta
|
|
463
|
-
* @see device.watchDeviceOrientation
|
|
464
|
-
*/
|
|
465
|
-
beta: 0,
|
|
466
|
-
|
|
467
|
-
/**
|
|
468
|
-
* Device orientation Alpha property. Gives angle based on the rotation of the phone around its z axis.
|
|
469
|
-
* The z-axis is perpendicular to the phone, facing out from the center of the screen.
|
|
470
|
-
* @public
|
|
471
|
-
* @type {number}
|
|
472
|
-
* @readonly
|
|
473
|
-
* @name alpha
|
|
474
|
-
* @see device.watchDeviceOrientation
|
|
475
|
-
*/
|
|
476
|
-
alpha : 0,
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* a string representing the preferred language of the user, usually the language of the browser UI.
|
|
480
|
-
* (will default to "en" if the information is not available)
|
|
481
|
-
* @public
|
|
482
|
-
* @type {string}
|
|
483
|
-
* @readonly
|
|
484
|
-
* @see http://www.w3schools.com/tags/ref_language_codes.asp
|
|
485
|
-
* @name language
|
|
486
|
-
*/
|
|
487
|
-
language : typeof globalThis.navigator !== "undefined" ? globalThis.navigator.language || globalThis.navigator.browserLanguage || globalThis.navigator.userLanguage || "en" : "en",
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Specify whether to pause the game when losing focus
|
|
491
|
-
* @type {boolean}
|
|
492
|
-
* @default true
|
|
493
|
-
*/
|
|
494
|
-
pauseOnBlur : true,
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Specify whether to unpause the game when gaining focus
|
|
498
|
-
* @type {boolean}
|
|
499
|
-
* @default true
|
|
500
|
-
*/
|
|
501
|
-
resumeOnFocus : true,
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Specify whether to automatically bring the window to the front
|
|
505
|
-
* @type {boolean}
|
|
506
|
-
* @default true
|
|
507
|
-
*/
|
|
508
|
-
autoFocus : true,
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* Specify whether to stop the game when losing focus or not.
|
|
512
|
-
* The engine restarts on focus if this is enabled.
|
|
513
|
-
* @type {boolean}
|
|
514
|
-
* @default false
|
|
515
|
-
*/
|
|
516
|
-
stopOnBlur : false,
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* equals to true if the device browser supports OffScreenCanvas.
|
|
520
|
-
* @type {boolean}
|
|
521
|
-
* @readonly
|
|
522
|
-
* @name OffScreenCanvas
|
|
523
|
-
*/
|
|
524
|
-
OffscreenCanvas : false,
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
/**
|
|
528
|
-
* specify a function to execute when the Device is fully loaded and ready
|
|
529
|
-
* @function device.onReady
|
|
530
|
-
* @param {Function} fn the function to be executed
|
|
531
|
-
* @example
|
|
532
|
-
* // small game skeleton
|
|
533
|
-
* var game = {
|
|
534
|
-
* // called by the me.device.onReady function
|
|
535
|
-
* onload : function () {
|
|
536
|
-
* // init video
|
|
537
|
-
* if (!me.video.init('screen', 640, 480, true)) {
|
|
538
|
-
* alert("Sorry but your browser does not support html 5 canvas.");
|
|
539
|
-
* return;
|
|
540
|
-
* }
|
|
541
|
-
*
|
|
542
|
-
* // initialize the "audio"
|
|
543
|
-
* me.audio.init("mp3,ogg");
|
|
544
|
-
*
|
|
545
|
-
* // set callback for ressources loaded event
|
|
546
|
-
* me.loader.onload = this.loaded.bind(this);
|
|
547
|
-
*
|
|
548
|
-
* // set all ressources to be loaded
|
|
549
|
-
* me.loader.preload(game.assets);
|
|
550
|
-
*
|
|
551
|
-
* // load everything & display a loading screen
|
|
552
|
-
* me.state.change(me.state.LOADING);
|
|
553
|
-
* },
|
|
554
|
-
*
|
|
555
|
-
* // callback when everything is loaded
|
|
556
|
-
* loaded : function () {
|
|
557
|
-
* // define stuff
|
|
558
|
-
* // ....
|
|
559
|
-
*
|
|
560
|
-
* // change to the menu screen
|
|
561
|
-
* me.state.change(me.state.PLAY);
|
|
562
|
-
* }
|
|
563
|
-
* }, // game
|
|
564
|
-
*
|
|
565
|
-
* // "bootstrap"
|
|
566
|
-
* me.device.onReady(function () {
|
|
567
|
-
* game.onload();
|
|
568
|
-
* });
|
|
569
|
-
*/
|
|
570
|
-
onReady(fn) {
|
|
571
|
-
DOMContentLoaded(fn);
|
|
572
|
-
},
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* enable/disable swipe on WebView.
|
|
576
|
-
* @function device.enableSwipe
|
|
577
|
-
* @param {boolean} [enable=true] enable or disable swipe.
|
|
578
|
-
*/
|
|
579
|
-
enableSwipe(enable) {
|
|
580
|
-
var moveEvent = device.PointerEvent ? "pointermove" : (device.TouchEvent ? "touchmove" : "mousemove");
|
|
581
|
-
if (enable !== false) {
|
|
582
|
-
if (swipeEnabled === false) {
|
|
583
|
-
globalThis.document.removeEventListener(moveEvent, _disableSwipeFn);
|
|
584
|
-
swipeEnabled = true;
|
|
585
|
-
}
|
|
586
|
-
} else if (swipeEnabled === true) {
|
|
587
|
-
globalThis.document.addEventListener(moveEvent, _disableSwipeFn, { passive: false });
|
|
588
|
-
swipeEnabled = false;
|
|
589
|
-
}
|
|
590
|
-
},
|
|
591
|
-
|
|
592
|
-
/**
|
|
593
|
-
* Triggers a fullscreen request. Requires fullscreen support from the browser/device.
|
|
594
|
-
* @function device.requestFullscreen
|
|
595
|
-
* @param {object} [element=default canvas object] the element to be set in full-screen mode.
|
|
596
|
-
* @example
|
|
597
|
-
* // add a keyboard shortcut to toggle Fullscreen mode on/off
|
|
598
|
-
* me.input.bindKey(me.input.KEY.F, "toggleFullscreen");
|
|
599
|
-
* me.event.on(me.event.KEYDOWN, function (action, keyCode, edge) {
|
|
600
|
-
* // toggle fullscreen on/off
|
|
601
|
-
* if (action === "toggleFullscreen") {
|
|
602
|
-
* if (!me.device.isFullscreen) {
|
|
603
|
-
* me.device.requestFullscreen();
|
|
604
|
-
* } else {
|
|
605
|
-
* me.device.exitFullscreen();
|
|
606
|
-
* }
|
|
607
|
-
* }
|
|
608
|
-
* });
|
|
609
|
-
*/
|
|
610
|
-
requestFullscreen(element) {
|
|
611
|
-
if (this.hasFullscreenSupport) {
|
|
612
|
-
element = element || getParent();
|
|
613
|
-
element.requestFullscreen = prefixed("requestFullscreen", element) ||
|
|
614
|
-
element.mozRequestFullScreen;
|
|
615
|
-
|
|
616
|
-
element.requestFullscreen();
|
|
617
|
-
}
|
|
618
|
-
},
|
|
619
|
-
|
|
620
|
-
/**
|
|
621
|
-
* Exit fullscreen mode. Requires fullscreen support from the browser/device.
|
|
622
|
-
* @function device.exitFullscreen
|
|
623
|
-
*/
|
|
624
|
-
exitFullscreen() {
|
|
625
|
-
if (this.hasFullscreenSupport) {
|
|
626
|
-
document.exitFullscreen();
|
|
627
|
-
}
|
|
628
|
-
},
|
|
629
|
-
|
|
630
|
-
/**
|
|
631
|
-
* Return a string representing the orientation of the device screen.
|
|
632
|
-
* It can be "any", "natural", "landscape", "portrait", "portrait-primary", "portrait-secondary", "landscape-primary", "landscape-secondary"
|
|
633
|
-
* @function device.getScreenOrientation
|
|
634
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/Screen/orientation
|
|
635
|
-
* @returns {string} the screen orientation
|
|
636
|
-
*/
|
|
637
|
-
getScreenOrientation() {
|
|
638
|
-
var PORTRAIT = "portrait";
|
|
639
|
-
var LANDSCAPE = "landscape";
|
|
640
|
-
|
|
641
|
-
var screen = globalThis.screen;
|
|
642
|
-
|
|
643
|
-
// first try using "standard" values
|
|
644
|
-
if (this.ScreenOrientation === true) {
|
|
645
|
-
var orientation = prefixed("orientation", screen);
|
|
646
|
-
if (typeof orientation !== "undefined" && typeof orientation.type === "string") {
|
|
647
|
-
// Screen Orientation API specification
|
|
648
|
-
return orientation.type;
|
|
649
|
-
} else if (typeof orientation === "string") {
|
|
650
|
-
// moz/ms-orientation are strings
|
|
651
|
-
return orientation;
|
|
652
|
-
}
|
|
653
|
-
}
|
|
635
|
+
export function getParentElement(element) {
|
|
636
|
+
let target = getElement(element);
|
|
654
637
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
}
|
|
638
|
+
if (target.parentNode !== null) {
|
|
639
|
+
target = target.parentNode;
|
|
640
|
+
}
|
|
659
641
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
},
|
|
663
|
-
|
|
664
|
-
/**
|
|
665
|
-
* locks the device screen into the specified orientation.<br>
|
|
666
|
-
* This method only works for installed Web apps or for Web pages in full-screen mode.
|
|
667
|
-
* @function device.lockOrientation
|
|
668
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation
|
|
669
|
-
* @param {string|string[]} orientation The orientation into which to lock the screen.
|
|
670
|
-
* @returns {boolean} true if the orientation was unsuccessfully locked
|
|
671
|
-
*/
|
|
672
|
-
lockOrientation(orientation) {
|
|
673
|
-
var screen = globalThis.screen;
|
|
674
|
-
if (typeof screen !== "undefined") {
|
|
675
|
-
var _lockOrientation = prefixed("lockOrientation", screen);
|
|
676
|
-
if (typeof _lockOrientation !== "undefined") {
|
|
677
|
-
return _lockOrientation(orientation);
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
return false;
|
|
681
|
-
},
|
|
682
|
-
|
|
683
|
-
/**
|
|
684
|
-
* unlocks the device screen into the specified orientation.<br>
|
|
685
|
-
* This method only works for installed Web apps or for Web pages in full-screen mode.
|
|
686
|
-
* @function device.unlockOrientation
|
|
687
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation
|
|
688
|
-
* @returns {boolean} true if the orientation was unsuccessfully unlocked
|
|
689
|
-
*/
|
|
690
|
-
unlockOrientation() {
|
|
691
|
-
var screen = globalThis.screen;
|
|
692
|
-
if (typeof screen !== "undefined") {
|
|
693
|
-
var _unlockOrientation = prefixed("unlockOrientation", screen);
|
|
694
|
-
if (typeof _unlockOrientation !== "undefined") {
|
|
695
|
-
return _unlockOrientation();
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
return false;
|
|
699
|
-
},
|
|
700
|
-
|
|
701
|
-
/**
|
|
702
|
-
* return true if the device screen orientation is in Portrait mode
|
|
703
|
-
* @function device.isPortrait
|
|
704
|
-
* @returns {boolean}
|
|
705
|
-
*/
|
|
706
|
-
isPortrait() {
|
|
707
|
-
return this.getScreenOrientation().includes("portrait");
|
|
708
|
-
},
|
|
709
|
-
|
|
710
|
-
/**
|
|
711
|
-
* return true if the device screen orientation is in Portrait mode
|
|
712
|
-
* @function device.isLandscape
|
|
713
|
-
* @returns {boolean}
|
|
714
|
-
*/
|
|
715
|
-
isLandscape() {
|
|
716
|
-
return this.getScreenOrientation().includes("landscape");
|
|
717
|
-
},
|
|
718
|
-
|
|
719
|
-
/**
|
|
720
|
-
* return the device storage
|
|
721
|
-
* @function device.getStorage
|
|
722
|
-
* @see save
|
|
723
|
-
* @param {string} [type="local"]
|
|
724
|
-
* @returns {object} a reference to the device storage
|
|
725
|
-
*/
|
|
726
|
-
getStorage(type = "local") {
|
|
727
|
-
switch (type) {
|
|
728
|
-
case "local" :
|
|
729
|
-
return save;
|
|
730
|
-
|
|
731
|
-
default :
|
|
732
|
-
throw new Error("storage type " + type + " not supported");
|
|
733
|
-
}
|
|
734
|
-
},
|
|
735
|
-
|
|
736
|
-
/**
|
|
737
|
-
* return the parent DOM element for the given parent name or HTMLElement object
|
|
738
|
-
* @function device.getParentElement
|
|
739
|
-
* @param {string|HTMLElement} element the parent element name or a HTMLElement object
|
|
740
|
-
* @returns {HTMLElement} the parent Element
|
|
741
|
-
*/
|
|
742
|
-
getParentElement(element) {
|
|
743
|
-
var target = this.getElement(element);
|
|
744
|
-
|
|
745
|
-
if (target.parentNode !== null) {
|
|
746
|
-
target = target.parentNode;
|
|
747
|
-
}
|
|
642
|
+
return target;
|
|
643
|
+
};
|
|
748
644
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
if (element
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
target = element;
|
|
766
|
-
}
|
|
645
|
+
/**
|
|
646
|
+
* return the DOM element for the given element name or HTMLElement object
|
|
647
|
+
* @function getElement
|
|
648
|
+
* @memberof device
|
|
649
|
+
* @public
|
|
650
|
+
* @param {string|HTMLElement} element the parent element name or a HTMLElement object
|
|
651
|
+
* @returns {HTMLElement} the corresponding DOM Element or null if not existing
|
|
652
|
+
*/
|
|
653
|
+
export function getElement(element) {
|
|
654
|
+
let target = null;
|
|
655
|
+
|
|
656
|
+
if (element !== "undefined") {
|
|
657
|
+
if (typeof element === "string") {
|
|
658
|
+
target = document.getElementById(element);
|
|
659
|
+
} else if (typeof element === "object" && element.nodeType === Node.ELEMENT_NODE) {
|
|
660
|
+
target = element;
|
|
767
661
|
}
|
|
662
|
+
}
|
|
768
663
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
664
|
+
// fallback, if invalid target or non HTMLElement object
|
|
665
|
+
if (!target) {
|
|
666
|
+
//default to document.body
|
|
667
|
+
target = document.body;
|
|
668
|
+
}
|
|
774
669
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
670
|
+
return target;
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* returns the size of the given HTMLElement and its position relative to the viewport
|
|
675
|
+
* <br><img src="images/element-box-diagram.png"/>
|
|
676
|
+
* @function getElementBounds
|
|
677
|
+
* @memberof device
|
|
678
|
+
* @public
|
|
679
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMRect
|
|
680
|
+
* @param {string|HTMLElement} element an HTMLElement object
|
|
681
|
+
* @returns {DOMRect} the size and position of the element relatively to the viewport
|
|
682
|
+
*/
|
|
683
|
+
export function getElementBounds(element) {
|
|
684
|
+
if (typeof element === "object" && element !== document.body && typeof element.getBoundingClientRect !== "undefined") {
|
|
685
|
+
return element.getBoundingClientRect();
|
|
686
|
+
} else {
|
|
687
|
+
domRect.width = domRect.right = globalThis.innerWidth;
|
|
688
|
+
domRect.height = domRect.bottom = globalThis.innerHeight;
|
|
689
|
+
return domRect;
|
|
690
|
+
};
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* returns the size of the given HTMLElement Parent and its position relative to the viewport
|
|
695
|
+
* <br><img src="images/element-box-diagram.png"/>
|
|
696
|
+
* @function getParentBounds
|
|
697
|
+
* @memberof device
|
|
698
|
+
* @public
|
|
699
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMRect
|
|
700
|
+
* @param {string|HTMLElement} element an HTMLElement object
|
|
701
|
+
* @returns {DOMRect} the size and position of the given element parent relative to the viewport
|
|
702
|
+
*/
|
|
703
|
+
export function getParentBounds(element) {
|
|
704
|
+
return getElementBounds(getParentElement(element));
|
|
705
|
+
};
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* returns true if the device supports WebGL
|
|
709
|
+
* @function isWebGLSupported
|
|
710
|
+
* @memberof device
|
|
711
|
+
* @public
|
|
712
|
+
* @param {object} [options] context creation options
|
|
713
|
+
* @param {boolean} [options.failIfMajorPerformanceCaveat=true] If true, the renderer will switch to CANVAS mode if the performances of a WebGL context would be dramatically lower than that of a native application making equivalent OpenGL calls.
|
|
714
|
+
* @returns {boolean} true if WebGL is supported
|
|
715
|
+
*/
|
|
716
|
+
export function isWebGLSupported(options) {
|
|
717
|
+
let _supported = false;
|
|
718
|
+
try {
|
|
719
|
+
let canvas = document.createElement("canvas");
|
|
720
|
+
let ctxOptions = {
|
|
721
|
+
stencil: true,
|
|
722
|
+
failIfMajorPerformanceCaveat: options.failIfMajorPerformanceCaveat
|
|
793
723
|
};
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
* <br><img src="images/element-box-diagram.png"/>
|
|
799
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMRect
|
|
800
|
-
* @function device.getParentBounds
|
|
801
|
-
* @param {string|HTMLElement} element an HTMLElement object
|
|
802
|
-
* @returns {DOMRect} the size and position of the given element parent relative to the viewport
|
|
803
|
-
*/
|
|
804
|
-
getParentBounds(element) {
|
|
805
|
-
return this.getElementBounds(this.getParentElement(element));
|
|
806
|
-
},
|
|
807
|
-
|
|
808
|
-
/**
|
|
809
|
-
* returns true if the device supports WebGL
|
|
810
|
-
* @function device.isWebGLSupported
|
|
811
|
-
* @param {object} [options] context creation options
|
|
812
|
-
* @param {boolean} [options.failIfMajorPerformanceCaveat=true] If true, the renderer will switch to CANVAS mode if the performances of a WebGL context would be dramatically lower than that of a native application making equivalent OpenGL calls.
|
|
813
|
-
* @returns {boolean} true if WebGL is supported
|
|
814
|
-
*/
|
|
815
|
-
isWebGLSupported(options) {
|
|
816
|
-
var _supported = false;
|
|
817
|
-
try {
|
|
818
|
-
var canvas = document.createElement("canvas");
|
|
819
|
-
var ctxOptions = {
|
|
820
|
-
stencil: true,
|
|
821
|
-
failIfMajorPerformanceCaveat : options.failIfMajorPerformanceCaveat
|
|
822
|
-
};
|
|
823
|
-
_supported = !! (globalThis.WebGLRenderingContext && (canvas.getContext("webgl", ctxOptions) || canvas.getContext("experimental-webgl", ctxOptions)));
|
|
824
|
-
} catch (e) {
|
|
825
|
-
_supported = false;
|
|
826
|
-
}
|
|
724
|
+
_supported = !! (globalThis.WebGLRenderingContext && (canvas.getContext("webgl", ctxOptions) || canvas.getContext("experimental-webgl", ctxOptions)));
|
|
725
|
+
} catch (e) {
|
|
726
|
+
_supported = false;
|
|
727
|
+
}
|
|
827
728
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
},
|
|
848
|
-
|
|
849
|
-
/**
|
|
850
|
-
* Makes a request to bring this device window to the front.
|
|
851
|
-
* @function device.focus
|
|
852
|
-
* @example
|
|
853
|
-
* if (clicked) {
|
|
854
|
-
* me.device.focus();
|
|
855
|
-
* }
|
|
856
|
-
*/
|
|
857
|
-
focus() {
|
|
858
|
-
if (typeof (globalThis.focus) === "function") {
|
|
859
|
-
globalThis.focus();
|
|
860
|
-
}
|
|
861
|
-
},
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
/**
|
|
865
|
-
* event management (Accelerometer)
|
|
866
|
-
* http://www.mobilexweb.com/samples/ball.html
|
|
867
|
-
* http://www.mobilexweb.com/blog/safari-ios-accelerometer-websockets-html5
|
|
868
|
-
* @ignore
|
|
869
|
-
*/
|
|
870
|
-
onDeviceMotion(e) {
|
|
871
|
-
// Accelerometer information
|
|
872
|
-
this.accelerationX = e.accelerationIncludingGravity.x;
|
|
873
|
-
this.accelerationY = e.accelerationIncludingGravity.y;
|
|
874
|
-
this.accelerationZ = e.accelerationIncludingGravity.z;
|
|
875
|
-
},
|
|
876
|
-
|
|
877
|
-
/**
|
|
878
|
-
* event management (Accelerometer)
|
|
879
|
-
* @ignore
|
|
880
|
-
*/
|
|
881
|
-
onDeviceRotate(e) {
|
|
882
|
-
this.gamma = e.gamma;
|
|
883
|
-
this.beta = e.beta;
|
|
884
|
-
this.alpha = e.alpha;
|
|
885
|
-
},
|
|
886
|
-
|
|
887
|
-
/**
|
|
888
|
-
* Enable monitor of the device accelerator to detect the amount of physical force of acceleration the device is receiving.
|
|
889
|
-
* (one some device a first user gesture will be required before calling this function)
|
|
890
|
-
* @function device.watchAccelerometer
|
|
891
|
-
* @see device.accelerationX
|
|
892
|
-
* @see device.accelerationY
|
|
893
|
-
* @see device.accelerationZ
|
|
894
|
-
* @returns {boolean} false if not supported or permission not granted by the user
|
|
895
|
-
* @example
|
|
896
|
-
* // try to enable device accelerometer event on user gesture
|
|
897
|
-
* me.input.registerPointerEvent("pointerleave", me.game.viewport, function() {
|
|
898
|
-
* if (me.device.watchAccelerometer() === true) {
|
|
899
|
-
* // Success
|
|
900
|
-
* me.input.releasePointerEvent("pointerleave", me.game.viewport);
|
|
901
|
-
* } else {
|
|
902
|
-
* // ... fail at enabling the device accelerometer event
|
|
903
|
-
* }
|
|
904
|
-
* });
|
|
905
|
-
*/
|
|
906
|
-
watchAccelerometer() {
|
|
907
|
-
if (this.hasAccelerometer && !accelInitialized) {
|
|
908
|
-
if (DeviceOrientationEvent && typeof DeviceOrientationEvent.requestPermission === "function") {
|
|
909
|
-
DeviceOrientationEvent.requestPermission()
|
|
910
|
-
.then(response => {
|
|
911
|
-
if (response === "granted") {
|
|
912
|
-
// add a listener for the devicemotion event
|
|
913
|
-
globalThis.addEventListener("devicemotion", this.onDeviceMotion, false);
|
|
914
|
-
accelInitialized = true;
|
|
915
|
-
}
|
|
916
|
-
}).catch(console.error);
|
|
917
|
-
} else {
|
|
918
|
-
// add a listener for the devicemotion event
|
|
919
|
-
globalThis.addEventListener("devicemotion", this.onDeviceMotion, false);
|
|
920
|
-
accelInitialized = true;
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
return accelInitialized;
|
|
924
|
-
},
|
|
925
|
-
|
|
926
|
-
/**
|
|
927
|
-
* unwatch Accelerometor event
|
|
928
|
-
* @function device.unwatchAccelerometer
|
|
929
|
-
*/
|
|
930
|
-
unwatchAccelerometer() {
|
|
931
|
-
if (accelInitialized) {
|
|
932
|
-
// remove the listener for the devicemotion event
|
|
933
|
-
globalThis.removeEventListener("devicemotion", this.onDeviceMotion, false);
|
|
934
|
-
accelInitialized = false;
|
|
935
|
-
}
|
|
936
|
-
},
|
|
937
|
-
|
|
938
|
-
/**
|
|
939
|
-
* Enable monitor of the device orientation to detect the current orientation of the device as compared to the Earth coordinate frame.
|
|
940
|
-
* (one some device a first user gesture will be required before calling this function)
|
|
941
|
-
* @function device.watchDeviceOrientation
|
|
942
|
-
* @see device.alpha
|
|
943
|
-
* @see device.beta
|
|
944
|
-
* @see device.gamma
|
|
945
|
-
* @returns {boolean} false if not supported or permission not granted by the user
|
|
946
|
-
* @example
|
|
947
|
-
* // try to enable device orientation event on user gesture
|
|
948
|
-
* me.input.registerPointerEvent("pointerleave", me.game.viewport, function() {
|
|
949
|
-
* if (me.device.watchDeviceOrientation() === true) {
|
|
950
|
-
* // Success
|
|
951
|
-
* me.input.releasePointerEvent("pointerleave", me.game.viewport);
|
|
952
|
-
* } else {
|
|
953
|
-
* // ... fail at enabling the device orientation event
|
|
954
|
-
* }
|
|
955
|
-
* });
|
|
956
|
-
*/
|
|
957
|
-
watchDeviceOrientation() {
|
|
958
|
-
if (this.hasDeviceOrientation && !deviceOrientationInitialized) {
|
|
959
|
-
if (typeof DeviceOrientationEvent.requestPermission === "function") {
|
|
960
|
-
DeviceOrientationEvent.requestPermission()
|
|
961
|
-
.then(response => {
|
|
962
|
-
if (response === "granted") {
|
|
963
|
-
globalThis.addEventListener("deviceorientation", this.onDeviceRotate, false);
|
|
964
|
-
deviceOrientationInitialized = true;
|
|
965
|
-
}
|
|
966
|
-
}).catch(console.error);
|
|
967
|
-
} else {
|
|
968
|
-
globalThis.addEventListener("deviceorientation", this.onDeviceRotate, false);
|
|
969
|
-
deviceOrientationInitialized = true;
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
return deviceOrientationInitialized;
|
|
973
|
-
},
|
|
974
|
-
|
|
975
|
-
/**
|
|
976
|
-
* unwatch Device orientation event
|
|
977
|
-
* @function device.unwatchDeviceOrientation
|
|
978
|
-
*/
|
|
979
|
-
unwatchDeviceOrientation() {
|
|
980
|
-
if (deviceOrientationInitialized) {
|
|
981
|
-
globalThis.removeEventListener("deviceorientation", this.onDeviceRotate, false);
|
|
982
|
-
deviceOrientationInitialized = false;
|
|
983
|
-
}
|
|
984
|
-
},
|
|
985
|
-
|
|
986
|
-
/**
|
|
987
|
-
* the vibrate method pulses the vibration hardware on the device, <br>
|
|
988
|
-
* If the device doesn't support vibration, this method has no effect. <br>
|
|
989
|
-
* If a vibration pattern is already in progress when this method is called,
|
|
990
|
-
* the previous pattern is halted and the new one begins instead.
|
|
991
|
-
* @function device.vibrate
|
|
992
|
-
* @param {number|number[]} pattern pattern of vibration and pause intervals
|
|
993
|
-
* @example
|
|
994
|
-
* // vibrate for 1000 ms
|
|
995
|
-
* me.device.vibrate(1000);
|
|
996
|
-
* // or alternatively
|
|
997
|
-
* me.device.vibrate([1000]);
|
|
998
|
-
* // vibrate for 50 ms, be still for 100 ms, and then vibrate for 150 ms:
|
|
999
|
-
* me.device.vibrate([50, 100, 150]);
|
|
1000
|
-
* // cancel any existing vibrations
|
|
1001
|
-
* me.device.vibrate(0);
|
|
1002
|
-
*/
|
|
1003
|
-
vibrate(pattern) {
|
|
1004
|
-
if (typeof globalThis.navigator !== "undefined" && typeof globalThis.navigator.vibrate === "function") {
|
|
1005
|
-
globalThis.navigator.vibrate(pattern);
|
|
1006
|
-
}
|
|
729
|
+
return _supported;
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* return the highest precision format supported by this device for GL Shaders
|
|
734
|
+
* @function getMaxShaderPrecision
|
|
735
|
+
* @memberof device
|
|
736
|
+
* @public
|
|
737
|
+
* @param {WebGLRenderingContext} gl
|
|
738
|
+
* @returns {boolean} "lowp", "mediump", or "highp"
|
|
739
|
+
*/
|
|
740
|
+
export function getMaxShaderPrecision(gl) {
|
|
741
|
+
if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
|
|
742
|
+
gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0) {
|
|
743
|
+
return "highp";
|
|
744
|
+
}
|
|
745
|
+
if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
|
|
746
|
+
gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0) {
|
|
747
|
+
return "mediump";
|
|
1007
748
|
}
|
|
749
|
+
return "lowp";
|
|
750
|
+
};
|
|
1008
751
|
|
|
752
|
+
/**
|
|
753
|
+
* Makes a request to bring this device window to the front.
|
|
754
|
+
* @function focus
|
|
755
|
+
* @memberof device
|
|
756
|
+
* @public
|
|
757
|
+
* @example
|
|
758
|
+
* if (clicked) {
|
|
759
|
+
* me.device.focus();
|
|
760
|
+
* }
|
|
761
|
+
*/
|
|
762
|
+
export function focus() {
|
|
763
|
+
if (typeof (globalThis.focus) === "function") {
|
|
764
|
+
globalThis.focus();
|
|
765
|
+
}
|
|
1009
766
|
};
|
|
1010
767
|
|
|
1011
768
|
/**
|
|
1012
|
-
*
|
|
1013
|
-
*
|
|
769
|
+
* Enable monitor of the device accelerator to detect the amount of physical force of acceleration the device is receiving.
|
|
770
|
+
* (one some device a first user gesture will be required before calling this function)
|
|
771
|
+
* @function watchAccelerometer
|
|
772
|
+
* @memberof device
|
|
1014
773
|
* @public
|
|
1015
|
-
* @
|
|
1016
|
-
* @
|
|
1017
|
-
* @
|
|
774
|
+
* @see device.accelerationX
|
|
775
|
+
* @see device.accelerationY
|
|
776
|
+
* @see device.accelerationZ
|
|
777
|
+
* @link {http://www.mobilexweb.com/samples/ball.html}
|
|
778
|
+
* @link {http://www.mobilexweb.com/blog/safari-ios-accelerometer-websockets-html5}
|
|
779
|
+
* @returns {boolean} false if not supported or permission not granted by the user
|
|
780
|
+
* @example
|
|
781
|
+
* // try to enable device accelerometer event on user gesture
|
|
782
|
+
* me.input.registerPointerEvent("pointerleave", me.game.viewport, function() {
|
|
783
|
+
* if (me.device.watchAccelerometer() === true) {
|
|
784
|
+
* // Success
|
|
785
|
+
* me.input.releasePointerEvent("pointerleave", me.game.viewport);
|
|
786
|
+
* } else {
|
|
787
|
+
* // ... fail at enabling the device accelerometer event
|
|
788
|
+
* }
|
|
789
|
+
* });
|
|
1018
790
|
*/
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
791
|
+
export function watchAccelerometer() {
|
|
792
|
+
if (hasAccelerometer && !accelInitialized) {
|
|
793
|
+
if (DeviceOrientationEvent && typeof DeviceOrientationEvent.requestPermission === "function") {
|
|
794
|
+
DeviceOrientationEvent.requestPermission()
|
|
795
|
+
.then(response => {
|
|
796
|
+
if (response === "granted") {
|
|
797
|
+
// add a listener for the devicemotion event
|
|
798
|
+
globalThis.addEventListener("devicemotion", onDeviceMotion, false);
|
|
799
|
+
accelInitialized = true;
|
|
800
|
+
}
|
|
801
|
+
}).catch(console.error);
|
|
802
|
+
} else {
|
|
803
|
+
// add a listener for the devicemotion event
|
|
804
|
+
globalThis.addEventListener("devicemotion", onDeviceMotion, false);
|
|
805
|
+
accelInitialized = true;
|
|
806
|
+
}
|
|
1025
807
|
}
|
|
1026
|
-
|
|
808
|
+
return accelInitialized;
|
|
809
|
+
};
|
|
1027
810
|
|
|
1028
811
|
/**
|
|
1029
|
-
*
|
|
1030
|
-
* @
|
|
812
|
+
* unwatch Accelerometor event
|
|
813
|
+
* @function unwatchAccelerometer
|
|
814
|
+
* @memberof device
|
|
1031
815
|
* @public
|
|
1032
|
-
* @member {boolean}
|
|
1033
|
-
* @readonly
|
|
1034
|
-
* @returns {boolean}
|
|
1035
816
|
*/
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
817
|
+
export function unwatchAccelerometer() {
|
|
818
|
+
if (accelInitialized) {
|
|
819
|
+
// remove the listener for the devicemotion event
|
|
820
|
+
globalThis.removeEventListener("devicemotion", onDeviceMotion, false);
|
|
821
|
+
accelInitialized = false;
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Enable monitor of the device orientation to detect the current orientation of the device as compared to the Earth coordinate frame.
|
|
827
|
+
* (one some device a first user gesture will be required before calling this function)
|
|
828
|
+
* @function watchDeviceOrientation
|
|
829
|
+
* @memberof device
|
|
830
|
+
* @public
|
|
831
|
+
* @see device.alpha
|
|
832
|
+
* @see device.beta
|
|
833
|
+
* @see device.gamma
|
|
834
|
+
* @returns {boolean} false if not supported or permission not granted by the user
|
|
835
|
+
* @example
|
|
836
|
+
* // try to enable device orientation event on user gesture
|
|
837
|
+
* me.input.registerPointerEvent("pointerleave", me.game.viewport, function() {
|
|
838
|
+
* if (me.device.watchDeviceOrientation() === true) {
|
|
839
|
+
* // Success
|
|
840
|
+
* me.input.releasePointerEvent("pointerleave", me.game.viewport);
|
|
841
|
+
* } else {
|
|
842
|
+
* // ... fail at enabling the device orientation event
|
|
843
|
+
* }
|
|
844
|
+
* });
|
|
845
|
+
*/
|
|
846
|
+
export function watchDeviceOrientation() {
|
|
847
|
+
if (hasDeviceOrientation && !deviceOrientationInitialized) {
|
|
848
|
+
if (typeof DeviceOrientationEvent.requestPermission === "function") {
|
|
849
|
+
DeviceOrientationEvent.requestPermission()
|
|
850
|
+
.then(response => {
|
|
851
|
+
if (response === "granted") {
|
|
852
|
+
globalThis.addEventListener("deviceorientation", onDeviceRotate, false);
|
|
853
|
+
deviceOrientationInitialized = true;
|
|
854
|
+
}
|
|
855
|
+
}).catch(console.error);
|
|
1044
856
|
} else {
|
|
1045
|
-
|
|
857
|
+
globalThis.addEventListener("deviceorientation", onDeviceRotate, false);
|
|
858
|
+
deviceOrientationInitialized = true;
|
|
1046
859
|
}
|
|
1047
860
|
}
|
|
1048
|
-
|
|
861
|
+
return deviceOrientationInitialized;
|
|
862
|
+
};
|
|
1049
863
|
|
|
1050
864
|
/**
|
|
1051
|
-
*
|
|
1052
|
-
* @
|
|
865
|
+
* unwatch Device orientation event
|
|
866
|
+
* @function unwatchDeviceOrientation
|
|
867
|
+
* @memberof device
|
|
1053
868
|
* @public
|
|
1054
|
-
* @member {boolean}
|
|
1055
|
-
* @readonly
|
|
1056
|
-
* @returns {boolean}
|
|
1057
869
|
*/
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
get: function () {
|
|
1063
|
-
return hasAudio();
|
|
870
|
+
export function unwatchDeviceOrientation() {
|
|
871
|
+
if (deviceOrientationInitialized) {
|
|
872
|
+
globalThis.removeEventListener("deviceorientation", onDeviceRotate, false);
|
|
873
|
+
deviceOrientationInitialized = false;
|
|
1064
874
|
}
|
|
1065
|
-
}
|
|
875
|
+
};
|
|
1066
876
|
|
|
1067
|
-
|
|
877
|
+
/**
|
|
878
|
+
* the vibrate method pulses the vibration hardware on the device, <br>
|
|
879
|
+
* If the device doesn't support vibration, this method has no effect. <br>
|
|
880
|
+
* If a vibration pattern is already in progress when this method is called,
|
|
881
|
+
* the previous pattern is halted and the new one begins instead.
|
|
882
|
+
* @function vibrate
|
|
883
|
+
* @memberof device
|
|
884
|
+
* @public
|
|
885
|
+
* @param {number|number[]} pattern pattern of vibration and pause intervals
|
|
886
|
+
* @example
|
|
887
|
+
* // vibrate for 1000 ms
|
|
888
|
+
* me.device.vibrate(1000);
|
|
889
|
+
* // or alternatively
|
|
890
|
+
* me.device.vibrate([1000]);
|
|
891
|
+
* // vibrate for 50 ms, be still for 100 ms, and then vibrate for 150 ms:
|
|
892
|
+
* me.device.vibrate([50, 100, 150]);
|
|
893
|
+
* // cancel any existing vibrations
|
|
894
|
+
* me.device.vibrate(0);
|
|
895
|
+
*/
|
|
896
|
+
export function vibrate(pattern) {
|
|
897
|
+
if (typeof globalThis.navigator !== "undefined" && typeof globalThis.navigator.vibrate === "function") {
|
|
898
|
+
globalThis.navigator.vibrate(pattern);
|
|
899
|
+
}
|
|
900
|
+
};
|