@vpmedia/phaser 1.0.1 → 1.0.3
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/README.md +20 -3
- package/dist/phaser.cjs +1 -1
- package/dist/phaser.cjs.LICENSE.txt +1 -1
- package/dist/phaser.cjs.map +1 -1
- package/dist/phaser.js +1 -1
- package/dist/phaser.js.LICENSE.txt +1 -1
- package/dist/phaser.js.map +1 -1
- package/package.json +23 -17
- package/src/index.js +142 -0
- package/src/phaser/core/animation.js +355 -0
- package/src/phaser/core/animation_manager.js +238 -0
- package/src/phaser/core/animation_parser.js +133 -0
- package/src/phaser/core/array_set.js +107 -0
- package/src/phaser/core/cache.js +558 -0
- package/src/phaser/core/const.js +106 -0
- package/src/phaser/core/device.js +67 -0
- package/src/phaser/core/device_util.js +388 -0
- package/src/phaser/core/dom.js +207 -0
- package/src/phaser/core/event_manager.js +243 -0
- package/src/phaser/core/factory.js +74 -0
- package/src/phaser/core/frame.js +75 -0
- package/src/phaser/core/frame_data.js +84 -0
- package/src/phaser/core/frame_util.js +33 -0
- package/src/phaser/core/game.js +412 -0
- package/src/phaser/core/input.js +401 -0
- package/src/phaser/core/input_button.js +102 -0
- package/src/phaser/core/input_handler.js +687 -0
- package/src/phaser/core/input_mouse.js +289 -0
- package/src/phaser/core/input_mspointer.js +197 -0
- package/src/phaser/core/input_pointer.js +427 -0
- package/src/phaser/core/input_touch.js +157 -0
- package/src/phaser/core/loader.js +1057 -0
- package/src/phaser/core/loader_parser.js +109 -0
- package/src/phaser/core/raf.js +46 -0
- package/src/phaser/core/raf_fb.js +75 -0
- package/src/phaser/core/raf_to.js +34 -0
- package/src/phaser/core/scale_manager.js +806 -0
- package/src/phaser/core/scene.js +65 -0
- package/src/phaser/core/scene_manager.js +309 -0
- package/src/phaser/core/signal.js +175 -0
- package/src/phaser/core/signal_binding.js +69 -0
- package/src/phaser/core/sound.js +538 -0
- package/src/phaser/core/sound_manager.js +364 -0
- package/src/phaser/core/stage.js +108 -0
- package/src/phaser/core/time.js +203 -0
- package/src/phaser/core/timer.js +276 -0
- package/src/phaser/core/timer_event.js +21 -0
- package/src/phaser/core/tween.js +329 -0
- package/src/phaser/core/tween_data.js +258 -0
- package/src/phaser/core/tween_easing.js +341 -0
- package/src/phaser/core/tween_manager.js +185 -0
- package/src/phaser/core/world.js +18 -0
- package/src/phaser/display/bitmap_text.js +322 -0
- package/src/phaser/display/button.js +194 -0
- package/src/phaser/display/canvas/buffer.js +36 -0
- package/src/phaser/display/canvas/graphics.js +227 -0
- package/src/phaser/display/canvas/masker.js +39 -0
- package/src/phaser/display/canvas/pool.js +126 -0
- package/src/phaser/display/canvas/renderer.js +123 -0
- package/src/phaser/display/canvas/tinter.js +144 -0
- package/src/phaser/display/canvas/util.js +159 -0
- package/src/phaser/display/display_object.js +597 -0
- package/src/phaser/display/graphics.js +723 -0
- package/src/phaser/display/graphics_data.js +27 -0
- package/src/phaser/display/graphics_data_util.js +15 -0
- package/src/phaser/display/group.js +227 -0
- package/src/phaser/display/image.js +288 -0
- package/src/phaser/display/sprite_batch.js +15 -0
- package/src/phaser/display/sprite_util.js +250 -0
- package/src/phaser/display/text.js +1089 -0
- package/src/phaser/display/webgl/abstract_filter.js +25 -0
- package/src/phaser/display/webgl/base_texture.js +68 -0
- package/src/phaser/display/webgl/blend_manager.js +35 -0
- package/src/phaser/display/webgl/earcut.js +662 -0
- package/src/phaser/display/webgl/earcut_node.js +28 -0
- package/src/phaser/display/webgl/fast_sprite_batch.js +242 -0
- package/src/phaser/display/webgl/filter_manager.js +46 -0
- package/src/phaser/display/webgl/filter_texture.js +61 -0
- package/src/phaser/display/webgl/graphics.js +624 -0
- package/src/phaser/display/webgl/graphics_data.js +42 -0
- package/src/phaser/display/webgl/mask_manager.js +36 -0
- package/src/phaser/display/webgl/render_texture.js +81 -0
- package/src/phaser/display/webgl/renderer.js +234 -0
- package/src/phaser/display/webgl/shader/complex.js +74 -0
- package/src/phaser/display/webgl/shader/fast.js +97 -0
- package/src/phaser/display/webgl/shader/normal.js +225 -0
- package/src/phaser/display/webgl/shader/primitive.js +72 -0
- package/src/phaser/display/webgl/shader/strip.js +77 -0
- package/src/phaser/display/webgl/shader_manager.js +89 -0
- package/src/phaser/display/webgl/sprite_batch.js +320 -0
- package/src/phaser/display/webgl/stencil_manager.js +170 -0
- package/src/phaser/display/webgl/texture.js +117 -0
- package/src/phaser/display/webgl/texture_util.js +34 -0
- package/src/phaser/display/webgl/util.js +78 -0
- package/src/phaser/geom/circle.js +186 -0
- package/src/phaser/geom/ellipse.js +65 -0
- package/src/phaser/geom/line.js +190 -0
- package/src/phaser/geom/matrix.js +147 -0
- package/src/phaser/geom/point.js +164 -0
- package/src/phaser/geom/polygon.js +140 -0
- package/src/phaser/geom/rectangle.js +306 -0
- package/src/phaser/geom/rounded_rectangle.js +36 -0
- package/src/phaser/geom/util/circle.js +122 -0
- package/src/phaser/geom/util/ellipse.js +34 -0
- package/src/phaser/geom/util/line.js +135 -0
- package/src/phaser/geom/util/matrix.js +53 -0
- package/src/phaser/geom/util/point.js +296 -0
- package/src/phaser/geom/util/polygon.js +28 -0
- package/src/phaser/geom/util/rectangle.js +229 -0
- package/src/phaser/geom/util/rounded_rectangle.js +32 -0
- package/src/phaser/util/math.js +297 -0
- package/src/phaser/util/string.js +32 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Andras Csizmadia <andras@vpmedia.hu>
|
|
3
|
+
* @author Richard Davey <rich@photonstorm.com>
|
|
4
|
+
* @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export default class {
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
this.deviceReadyAt = 0;
|
|
11
|
+
this.desktop = false;
|
|
12
|
+
this.iOS = false;
|
|
13
|
+
this.iOSVersion = 0;
|
|
14
|
+
this.cocoonJS = false;
|
|
15
|
+
this.cocoonJSApp = false;
|
|
16
|
+
this.cordova = false;
|
|
17
|
+
this.node = false;
|
|
18
|
+
this.android = false;
|
|
19
|
+
this.chromeOS = false;
|
|
20
|
+
this.linux = false;
|
|
21
|
+
this.macOS = false;
|
|
22
|
+
this.windows = false;
|
|
23
|
+
this.windowsPhone = false;
|
|
24
|
+
this.canvas = false;
|
|
25
|
+
this.pointerLock = false;
|
|
26
|
+
this.touch = false;
|
|
27
|
+
this.mspointer = false;
|
|
28
|
+
this.wheelEvent = null;
|
|
29
|
+
this.chrome = false;
|
|
30
|
+
this.chromeVersion = 0;
|
|
31
|
+
this.firefox = false;
|
|
32
|
+
this.firefoxVersion = 0;
|
|
33
|
+
this.ie = false;
|
|
34
|
+
this.ieVersion = 0;
|
|
35
|
+
this.trident = false;
|
|
36
|
+
this.tridentVersion = 0;
|
|
37
|
+
this.edge = false;
|
|
38
|
+
this.mobileSafari = false;
|
|
39
|
+
this.safari = false;
|
|
40
|
+
this.safariVersion = 0;
|
|
41
|
+
this.webApp = false;
|
|
42
|
+
this.silk = false;
|
|
43
|
+
this.audioData = false;
|
|
44
|
+
this.webAudio = false;
|
|
45
|
+
this.ogg = false;
|
|
46
|
+
this.opus = false;
|
|
47
|
+
this.mp3 = false;
|
|
48
|
+
this.wav = false;
|
|
49
|
+
this.m4a = false;
|
|
50
|
+
this.webm = false;
|
|
51
|
+
this.dolby = false;
|
|
52
|
+
this.oggVideo = false;
|
|
53
|
+
this.h264Video = false;
|
|
54
|
+
this.mp4Video = false;
|
|
55
|
+
this.webmVideo = false;
|
|
56
|
+
this.vp9Video = false;
|
|
57
|
+
this.hlsVideo = false;
|
|
58
|
+
this.iPhone = false;
|
|
59
|
+
this.iPad = false;
|
|
60
|
+
this.pixelRatio = 1;
|
|
61
|
+
this.fullscreen = false;
|
|
62
|
+
this.requestFullscreen = '';
|
|
63
|
+
this.cancelFullscreen = '';
|
|
64
|
+
this.fullscreenKeyboard = false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
}
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Andras Csizmadia <andras@vpmedia.hu>
|
|
3
|
+
* @author Richard Davey <rich@photonstorm.com>
|
|
4
|
+
* @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {object} device TBD
|
|
10
|
+
* @param {string} type TBD
|
|
11
|
+
* @returns {boolean} TBD
|
|
12
|
+
*/
|
|
13
|
+
export function canPlayAudio(device, type) {
|
|
14
|
+
if (type === 'mp3' && device.mp3) {
|
|
15
|
+
return true;
|
|
16
|
+
} else if (type === 'ogg' && (device.ogg || device.opus)) {
|
|
17
|
+
return true;
|
|
18
|
+
} else if (type === 'm4a' && device.m4a) {
|
|
19
|
+
return true;
|
|
20
|
+
} else if (type === 'opus' && device.opus) {
|
|
21
|
+
return true;
|
|
22
|
+
} else if (type === 'wav' && device.wav) {
|
|
23
|
+
return true;
|
|
24
|
+
} else if (type === 'webm' && device.webm) {
|
|
25
|
+
return true;
|
|
26
|
+
} else if (type === 'mp4' && device.dolby) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param {object} device TBD
|
|
35
|
+
* @param {string} type TBD
|
|
36
|
+
* @returns {boolean} TBD
|
|
37
|
+
*/
|
|
38
|
+
export function canPlayVideo(device, type) {
|
|
39
|
+
if (type === 'webm' && (device.webmVideo || device.vp9Video)) {
|
|
40
|
+
return true;
|
|
41
|
+
} else if (type === 'mp4' && (device.mp4Video || device.h264Video)) {
|
|
42
|
+
return true;
|
|
43
|
+
} else if ((type === 'ogg' || type === 'ogv') && device.oggVideo) {
|
|
44
|
+
return true;
|
|
45
|
+
} else if (type === 'mpeg' && device.hlsVideo) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
* @param {object} device TBD
|
|
54
|
+
*/
|
|
55
|
+
export function checkOS(device) {
|
|
56
|
+
const ua = navigator.userAgent;
|
|
57
|
+
if (/Android/.test(ua)) {
|
|
58
|
+
device.android = true;
|
|
59
|
+
} else if (/CrOS/.test(ua)) {
|
|
60
|
+
device.chromeOS = true;
|
|
61
|
+
} else if (/iP[ao]d|iPhone/i.test(ua)) {
|
|
62
|
+
device.iOS = true;
|
|
63
|
+
(navigator.appVersion).match(/OS (\d+)/);
|
|
64
|
+
device.iOSVersion = parseInt(RegExp.$1, 10);
|
|
65
|
+
} else if (/Linux/.test(ua)) {
|
|
66
|
+
device.linux = true;
|
|
67
|
+
} else if (/Mac OS/.test(ua)) {
|
|
68
|
+
device.macOS = true;
|
|
69
|
+
} else if (/Windows/.test(ua)) {
|
|
70
|
+
device.windows = true;
|
|
71
|
+
}
|
|
72
|
+
if (/Windows Phone/i.test(ua) || /IEMobile/i.test(ua)) {
|
|
73
|
+
device.android = false;
|
|
74
|
+
device.iOS = false;
|
|
75
|
+
device.macOS = false;
|
|
76
|
+
device.windows = true;
|
|
77
|
+
device.windowsPhone = true;
|
|
78
|
+
}
|
|
79
|
+
const silk = /Silk/.test(ua); // detected in browsers
|
|
80
|
+
if (device.windows || device.macOS || (device.linux && !silk) || device.chromeOS) {
|
|
81
|
+
device.desktop = true;
|
|
82
|
+
}
|
|
83
|
+
// Windows Phone / Table reset
|
|
84
|
+
if (device.windowsPhone || ((/Windows NT/i.test(ua)) && (/Touch/i.test(ua)))) {
|
|
85
|
+
device.desktop = false;
|
|
86
|
+
}
|
|
87
|
+
// VPMedia Special override
|
|
88
|
+
if (window.location.pathname.indexOf('/mobile/') > -1) {
|
|
89
|
+
device.desktop = false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
*
|
|
95
|
+
* @param {object} device TBD
|
|
96
|
+
*/
|
|
97
|
+
export function checkFeatures(device) {
|
|
98
|
+
device.pointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
* @param {object} device TBD
|
|
104
|
+
*/
|
|
105
|
+
export function checkInput(device) {
|
|
106
|
+
if ('ontouchstart' in document.documentElement || (window.navigator.maxTouchPoints && window.navigator.maxTouchPoints >= 1)) {
|
|
107
|
+
device.touch = true;
|
|
108
|
+
}
|
|
109
|
+
if (window.navigator.msPointerEnabled || window.navigator.pointerEnabled) {
|
|
110
|
+
device.mspointer = true;
|
|
111
|
+
}
|
|
112
|
+
if (!device.cocoonJS) {
|
|
113
|
+
// See https://developer.mozilla.org/en-US/docs/Web/Events/wheel
|
|
114
|
+
if ('onwheel' in window || (device.ie && 'WheelEvent' in window)) {
|
|
115
|
+
// DOM3 Wheel Event: FF 17+, IE 9+, Chrome 31+, Safari 7+
|
|
116
|
+
device.wheelEvent = 'wheel';
|
|
117
|
+
} else if ('onmousewheel' in window) {
|
|
118
|
+
// Non-FF legacy: IE 6-9, Chrome 1-31, Safari 5-7.
|
|
119
|
+
device.wheelEvent = 'mousewheel';
|
|
120
|
+
} else if (device.firefox && 'MouseScrollEvent' in window) {
|
|
121
|
+
// FF prior to 17. This should probably be scrubbed.
|
|
122
|
+
device.wheelEvent = 'DOMMouseScroll';
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
*
|
|
129
|
+
* @param {object} device TBD
|
|
130
|
+
*/
|
|
131
|
+
export function checkFullScreenSupport(device) {
|
|
132
|
+
const fs = [
|
|
133
|
+
'requestFullscreen',
|
|
134
|
+
'requestFullScreen',
|
|
135
|
+
'webkitRequestFullscreen',
|
|
136
|
+
'webkitRequestFullScreen',
|
|
137
|
+
'msRequestFullscreen',
|
|
138
|
+
'msRequestFullScreen',
|
|
139
|
+
'mozRequestFullScreen',
|
|
140
|
+
'mozRequestFullscreen',
|
|
141
|
+
];
|
|
142
|
+
const cfs = [
|
|
143
|
+
'cancelFullScreen',
|
|
144
|
+
'exitFullscreen',
|
|
145
|
+
'webkitCancelFullScreen',
|
|
146
|
+
'webkitExitFullscreen',
|
|
147
|
+
'msCancelFullScreen',
|
|
148
|
+
'msExitFullscreen',
|
|
149
|
+
'mozCancelFullScreen',
|
|
150
|
+
'mozExitFullscreen',
|
|
151
|
+
];
|
|
152
|
+
const element = document.createElement('div');
|
|
153
|
+
for (let i = 0; i < fs.length; i += 1) {
|
|
154
|
+
if (element[fs[i]]) {
|
|
155
|
+
device.fullscreen = true;
|
|
156
|
+
device.requestFullscreen = fs[i];
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (device.fullscreen) {
|
|
161
|
+
for (let i = 0; i < cfs.length; i += 1) {
|
|
162
|
+
if (document[cfs[i]]) {
|
|
163
|
+
device.cancelFullscreen = cfs[i];
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (window.Element && Element.ALLOW_KEYBOARD_INPUT) {
|
|
168
|
+
device.fullscreenKeyboard = true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
*
|
|
175
|
+
* @param {object} device TBD
|
|
176
|
+
*/
|
|
177
|
+
export function checkBrowser(device) {
|
|
178
|
+
const ua = navigator.userAgent;
|
|
179
|
+
if (/Edge\/\d+/.test(ua)) {
|
|
180
|
+
device.edge = true;
|
|
181
|
+
} else if (/Chrome\/(\d+)/.test(ua) && !device.windowsPhone) {
|
|
182
|
+
device.chrome = true;
|
|
183
|
+
device.chromeVersion = parseInt(RegExp.$1, 10);
|
|
184
|
+
} else if (/Firefox\D+(\d+)/.test(ua)) {
|
|
185
|
+
device.firefox = true;
|
|
186
|
+
device.firefoxVersion = parseInt(RegExp.$1, 10);
|
|
187
|
+
} else if (/AppleWebKit/.test(ua) && device.iOS) {
|
|
188
|
+
device.mobileSafari = true;
|
|
189
|
+
} else if (/MSIE (\d+\.\d+);/.test(ua)) {
|
|
190
|
+
device.ie = true;
|
|
191
|
+
device.ieVersion = parseInt(RegExp.$1, 10);
|
|
192
|
+
} else if (/Safari\/(\d+)/.test(ua) && !device.windowsPhone) {
|
|
193
|
+
device.safari = true;
|
|
194
|
+
if (/Version\/(\d+)\./.test(ua)) {
|
|
195
|
+
device.safariVersion = parseInt(RegExp.$1, 10);
|
|
196
|
+
}
|
|
197
|
+
} else if (/Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/.test(ua)) {
|
|
198
|
+
device.ie = true;
|
|
199
|
+
device.trident = true;
|
|
200
|
+
device.tridentVersion = parseInt(RegExp.$1, 10);
|
|
201
|
+
device.ieVersion = parseInt(RegExp.$3, 10);
|
|
202
|
+
}
|
|
203
|
+
// Silk gets its own if clause because its ua also contains 'Safari'
|
|
204
|
+
if (/Silk/.test(ua)) {
|
|
205
|
+
device.silk = true;
|
|
206
|
+
}
|
|
207
|
+
// WebApp mode in iOS
|
|
208
|
+
if (navigator.standalone) {
|
|
209
|
+
device.webApp = true;
|
|
210
|
+
}
|
|
211
|
+
if (typeof window.cordova !== 'undefined') {
|
|
212
|
+
device.cordova = true;
|
|
213
|
+
}
|
|
214
|
+
if (typeof process !== 'undefined' && typeof require !== 'undefined') {
|
|
215
|
+
device.node = true;
|
|
216
|
+
}
|
|
217
|
+
if (navigator.isCocoonJS) {
|
|
218
|
+
device.cocoonJS = true;
|
|
219
|
+
}
|
|
220
|
+
if (device.cocoonJS) {
|
|
221
|
+
try {
|
|
222
|
+
device.cocoonJSApp = (typeof CocoonJS !== 'undefined');
|
|
223
|
+
} catch (error) {
|
|
224
|
+
device.cocoonJSApp = false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
*
|
|
231
|
+
* @param {object} device TBD
|
|
232
|
+
*/
|
|
233
|
+
export function checkVideo(device) {
|
|
234
|
+
const videoElement = document.createElement('video');
|
|
235
|
+
try {
|
|
236
|
+
if (videoElement.canPlayType) {
|
|
237
|
+
if (videoElement.canPlayType('video/ogg; codecs="theora"').replace(/^no$/, '')) {
|
|
238
|
+
device.oggVideo = true;
|
|
239
|
+
}
|
|
240
|
+
if (videoElement.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/, '')) {
|
|
241
|
+
// Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
|
|
242
|
+
device.h264Video = true;
|
|
243
|
+
device.mp4Video = true;
|
|
244
|
+
}
|
|
245
|
+
if (videoElement.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/, '')) {
|
|
246
|
+
device.webmVideo = true;
|
|
247
|
+
}
|
|
248
|
+
if (videoElement.canPlayType('video/webm; codecs="vp9"').replace(/^no$/, '')) {
|
|
249
|
+
device.vp9Video = true;
|
|
250
|
+
}
|
|
251
|
+
if (videoElement.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(/^no$/, '')) {
|
|
252
|
+
device.hlsVideo = true;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
} catch (e) {
|
|
256
|
+
// pass
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
*
|
|
262
|
+
* @param {object} device TBD
|
|
263
|
+
*/
|
|
264
|
+
export function checkAudio(device) {
|
|
265
|
+
device.audioData = !!(window.Audio);
|
|
266
|
+
device.webAudio = !!(window.AudioContext || window.webkitAudioContext);
|
|
267
|
+
const audioElement = document.createElement('audio');
|
|
268
|
+
try {
|
|
269
|
+
if (audioElement.canPlayType) {
|
|
270
|
+
if (audioElement.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, '')) {
|
|
271
|
+
device.ogg = true;
|
|
272
|
+
}
|
|
273
|
+
if (audioElement.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/, '') || audioElement.canPlayType('audio/opus;').replace(/^no$/, '')) {
|
|
274
|
+
device.opus = true;
|
|
275
|
+
}
|
|
276
|
+
if (audioElement.canPlayType('audio/mpeg;').replace(/^no$/, '')) {
|
|
277
|
+
device.mp3 = true;
|
|
278
|
+
}
|
|
279
|
+
// Mimetypes accepted:
|
|
280
|
+
// developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
|
|
281
|
+
// bit.ly/iphoneoscodecs
|
|
282
|
+
if (audioElement.canPlayType('audio/wav; codecs="1"').replace(/^no$/, '')) {
|
|
283
|
+
device.wav = true;
|
|
284
|
+
}
|
|
285
|
+
if (audioElement.canPlayType('audio/x-m4a;') || audioElement.canPlayType('audio/aac;').replace(/^no$/, '')) {
|
|
286
|
+
device.m4a = true;
|
|
287
|
+
}
|
|
288
|
+
if (audioElement.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, '')) {
|
|
289
|
+
device.webm = true;
|
|
290
|
+
}
|
|
291
|
+
if (audioElement.canPlayType('audio/mp4;codecs="ec-3"') !== '') {
|
|
292
|
+
if (device.edge) {
|
|
293
|
+
device.dolby = true;
|
|
294
|
+
} else if (device.safari && device.safariVersion >= 9) {
|
|
295
|
+
if (/Mac OS X (\d+)_(\d+)/.test(navigator.userAgent)) {
|
|
296
|
+
const major = parseInt(RegExp.$1, 10);
|
|
297
|
+
const minor = parseInt(RegExp.$2, 10);
|
|
298
|
+
if ((major === 10 && minor >= 11) || major > 10) {
|
|
299
|
+
device.dolby = true;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
} catch (e) {
|
|
306
|
+
// pass
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
*
|
|
312
|
+
* @param {object} device TBD
|
|
313
|
+
*/
|
|
314
|
+
export function checkDevice(device) {
|
|
315
|
+
device.pixelRatio = window.devicePixelRatio || 1;
|
|
316
|
+
device.iPhone = navigator.userAgent.toLowerCase().indexOf('iphone') !== -1;
|
|
317
|
+
device.iPad = navigator.userAgent.toLowerCase().indexOf('ipad') !== -1;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
*
|
|
322
|
+
* @param {object} device TBD
|
|
323
|
+
*/
|
|
324
|
+
export function initialize(device) {
|
|
325
|
+
checkOS(device);
|
|
326
|
+
checkBrowser(device);
|
|
327
|
+
checkAudio(device);
|
|
328
|
+
checkVideo(device);
|
|
329
|
+
checkDevice(device);
|
|
330
|
+
checkFeatures(device);
|
|
331
|
+
checkFullScreenSupport(device);
|
|
332
|
+
checkInput(device);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* TBD
|
|
337
|
+
*/
|
|
338
|
+
export function readyCheck() {
|
|
339
|
+
if (!document.body) {
|
|
340
|
+
window.setTimeout(readyCheck._monitor, 20);
|
|
341
|
+
} else if (!this.deviceReadyAt) {
|
|
342
|
+
this.deviceReadyAt = Date.now();
|
|
343
|
+
document.removeEventListener('deviceready', readyCheck._monitor);
|
|
344
|
+
document.removeEventListener('DOMContentLoaded', readyCheck._monitor);
|
|
345
|
+
window.removeEventListener('load', readyCheck._monitor);
|
|
346
|
+
initialize(this);
|
|
347
|
+
let item = readyCheck._queue.shift();
|
|
348
|
+
while (item) {
|
|
349
|
+
const callback = item[0];
|
|
350
|
+
const context = item[1];
|
|
351
|
+
callback.call(context, this);
|
|
352
|
+
item = readyCheck._queue.shift();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
*
|
|
359
|
+
* @param {object} device TBD
|
|
360
|
+
* @param {Function} callback TBD
|
|
361
|
+
* @param {object} context TBD
|
|
362
|
+
* @param {boolean} nonPrimer TBD
|
|
363
|
+
*/
|
|
364
|
+
export function whenReady(device, callback, context, nonPrimer) {
|
|
365
|
+
if (device.deviceReadyAt) {
|
|
366
|
+
callback.call(context, device);
|
|
367
|
+
} else if (readyCheck._monitor || nonPrimer) {
|
|
368
|
+
readyCheck._queue = readyCheck._queue || [];
|
|
369
|
+
readyCheck._queue.push([callback, context]);
|
|
370
|
+
} else {
|
|
371
|
+
readyCheck._monitor = readyCheck.bind(device);
|
|
372
|
+
readyCheck._queue = readyCheck._queue || [];
|
|
373
|
+
readyCheck._queue.push([callback, context]);
|
|
374
|
+
const cordova = typeof window.cordova !== 'undefined';
|
|
375
|
+
const cocoonJS = navigator.isCocoonJS;
|
|
376
|
+
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
|
377
|
+
// Why is there an additional timeout here?
|
|
378
|
+
window.setTimeout(readyCheck._monitor, 0);
|
|
379
|
+
} else if (cordova && !cocoonJS) {
|
|
380
|
+
// Ref. http://docs.phonegap.com/en/3.5.0/cordova_events_events.md.html#deviceready
|
|
381
|
+
// Cordova, but NOT Cocoon?
|
|
382
|
+
document.addEventListener('deviceready', readyCheck._monitor, false);
|
|
383
|
+
} else {
|
|
384
|
+
document.addEventListener('DOMContentLoaded', readyCheck._monitor, false);
|
|
385
|
+
window.addEventListener('load', readyCheck._monitor, false);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Andras Csizmadia <andras@vpmedia.hu>
|
|
3
|
+
* @author Richard Davey <rich@photonstorm.com>
|
|
4
|
+
* @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
|
|
5
|
+
*/
|
|
6
|
+
import Point from '../geom/point';
|
|
7
|
+
|
|
8
|
+
class VisualBoundsDesktopRectangle {
|
|
9
|
+
|
|
10
|
+
get x() {
|
|
11
|
+
return window && ('pageXOffset' in window) ? window.pageXOffset : document.documentElement.scrollLeft;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
get y() {
|
|
15
|
+
return window && ('pageYOffset' in window) ? window.pageYOffset : document.documentElement.scrollTop;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get width() {
|
|
19
|
+
return Math.max(window.innerWidth, document.documentElement.clientWidth);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get height() {
|
|
23
|
+
return Math.max(window.innerHeight, document.documentElement.clientHeight);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class LayoutBoundsDesktopRectangle {
|
|
29
|
+
|
|
30
|
+
get x() {
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get y() {
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get width() {
|
|
39
|
+
return Math.max(window.innerWidth, document.documentElement.clientWidth);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get height() {
|
|
43
|
+
return Math.max(window.innerHeight, document.documentElement.clientHeight);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
class VisualBoundsRectangle {
|
|
49
|
+
|
|
50
|
+
get x() {
|
|
51
|
+
return window && ('pageXOffset' in window) ? window.pageXOffset : document.documentElement.scrollLeft;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get y() {
|
|
55
|
+
return window && ('pageYOffset' in window) ? window.pageYOffset : document.documentElement.scrollTop;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get width() {
|
|
59
|
+
return window.innerWidth;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get height() {
|
|
63
|
+
return window.innerHeight;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
class LayoutBoundsRectangle {
|
|
69
|
+
|
|
70
|
+
get x() {
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get y() {
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get width() {
|
|
79
|
+
const a = document.documentElement.clientWidth;
|
|
80
|
+
const b = window.innerWidth;
|
|
81
|
+
return a < b ? b : a; // max
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get height() {
|
|
85
|
+
const a = document.documentElement.clientHeight;
|
|
86
|
+
const b = window.innerHeight;
|
|
87
|
+
return a < b ? b : a; // max
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// For documentBounds
|
|
93
|
+
// Ref. http://www.quirksmode.org/mobile/tableViewport_desktop.html
|
|
94
|
+
|
|
95
|
+
class DocumentBoundsRectangle {
|
|
96
|
+
|
|
97
|
+
get x() {
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
get y() {
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
get width() {
|
|
106
|
+
const d = document.documentElement;
|
|
107
|
+
return Math.max(d.clientWidth, d.offsetWidth, d.scrollWidth);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get height() {
|
|
111
|
+
const d = document.documentElement;
|
|
112
|
+
return Math.max(d.clientHeight, d.offsetHeight, d.scrollHeight);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export default class {
|
|
118
|
+
|
|
119
|
+
constructor(device) {
|
|
120
|
+
this.treatAsDesktop = device.desktop && (document.documentElement.clientWidth <= window.innerWidth) && (document.documentElement.clientHeight <= window.innerHeight);
|
|
121
|
+
this.visualBounds = this.treatAsDesktop ? new VisualBoundsDesktopRectangle() : new VisualBoundsRectangle();
|
|
122
|
+
this.layoutBounds = this.treatAsDesktop ? new LayoutBoundsDesktopRectangle() : new LayoutBoundsRectangle();
|
|
123
|
+
this.documentBounds = new DocumentBoundsRectangle();
|
|
124
|
+
this.scrollXProvider = window && ('pageXOffset' in window) ? () => window.pageXOffset : () => document.documentElement.scrollLeft;
|
|
125
|
+
this.scrollYProvider = window && ('pageYOffset' in window) ? () => window.pageYOffset : () => document.documentElement.scrollTop;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
getOffset(element, point = null) {
|
|
129
|
+
point = point || new Point();
|
|
130
|
+
const box = element.getBoundingClientRect();
|
|
131
|
+
const scrollTop = this.scrollY;
|
|
132
|
+
const scrollLeft = this.scrollX;
|
|
133
|
+
const clientTop = document.documentElement.clientTop;
|
|
134
|
+
const clientLeft = document.documentElement.clientLeft;
|
|
135
|
+
point.x = box.left + scrollLeft - clientLeft;
|
|
136
|
+
point.y = box.top + scrollTop - clientTop;
|
|
137
|
+
return point;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
getBounds(element, cushion = 0) {
|
|
141
|
+
element = element && !element.nodeType ? element[0] : element;
|
|
142
|
+
if (!element || element.nodeType !== 1) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return this.calibrate(element.getBoundingClientRect(), cushion);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
calibrate(coords, cushion = 0) {
|
|
149
|
+
const output = {
|
|
150
|
+
width: 0,
|
|
151
|
+
height: 0,
|
|
152
|
+
left: 0,
|
|
153
|
+
right: 0,
|
|
154
|
+
top: 0,
|
|
155
|
+
bottom: 0,
|
|
156
|
+
};
|
|
157
|
+
output.width = (output.right = coords.right + cushion) - (output.left = coords.left - cushion);
|
|
158
|
+
output.height = (output.bottom = coords.bottom + cushion) - (output.top = coords.top - cushion);
|
|
159
|
+
return output;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
getScreenOrientation(primaryFallback) {
|
|
163
|
+
const screen = window.screen;
|
|
164
|
+
const orientation = screen.orientation || screen.mozOrientation || screen.msOrientation;
|
|
165
|
+
if (orientation && typeof orientation.type === 'string') {
|
|
166
|
+
// Screen Orientation API specification
|
|
167
|
+
return orientation.type;
|
|
168
|
+
} else if (typeof orientation === 'string') {
|
|
169
|
+
// moz/ms-orientation are strings
|
|
170
|
+
return orientation;
|
|
171
|
+
}
|
|
172
|
+
const PORTRAIT = 'portrait-primary';
|
|
173
|
+
const LANDSCAPE = 'landscape-primary';
|
|
174
|
+
if (primaryFallback === 'screen') {
|
|
175
|
+
return (screen.height > screen.width) ? PORTRAIT : LANDSCAPE;
|
|
176
|
+
} else if (primaryFallback === 'viewport') {
|
|
177
|
+
return (this.visualBounds.height > this.visualBounds.width) ? PORTRAIT : LANDSCAPE;
|
|
178
|
+
} else if (primaryFallback === 'window.orientation' && typeof window.orientation === 'number') {
|
|
179
|
+
// This may change by device based on "natural" orientation.
|
|
180
|
+
return (window.orientation === 0 || window.orientation === 180) ? PORTRAIT : LANDSCAPE;
|
|
181
|
+
} else if (window.matchMedia) {
|
|
182
|
+
if (window.matchMedia('(orientation: portrait)').matches) {
|
|
183
|
+
return PORTRAIT;
|
|
184
|
+
} else if (window.matchMedia('(orientation: landscape)').matches) {
|
|
185
|
+
return LANDSCAPE;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return (this.visualBounds.height > this.visualBounds.width) ? PORTRAIT : LANDSCAPE;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
get scrollX() {
|
|
192
|
+
return this.scrollXProvider();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
get scrollY() {
|
|
196
|
+
return this.scrollYProvider();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
get clientWidth() {
|
|
200
|
+
return Math.max(window.innerWidth, document.documentElement.clientWidth);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
get clientHeight() {
|
|
204
|
+
return Math.max(window.innerHeight, document.documentElement.clientHeight);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
}
|