-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
111 lines (111 loc) · 3.9 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
let _deviceOrientation_cachedEvent;
/**
* @param {Boolean} exactAngle - If it is set to true, then return a number from 0 up to 360, which represents current angle (rounded), otherwise it only returns 0, 90, 180 or 270 depending on which is more close to the current device angle
* @returns {Number} current angle of device, see exactAngle description for more details
*/
export function getDeviceOrientation(event, exactAngle = false) {
if (!event && !_deviceOrientation_cachedEvent) {
return 0;
}
else if (!event) {
event = _deviceOrientation_cachedEvent;
}
if (!event || !event.beta || !event.gamma) {
return 0;
}
// shoutout to https://stackoverflow.com/a/40720543
const x = event.beta; // In degree in the range [-180,180], x, 'front to back'
const y = event.gamma; // In degree in the range [-90,90], y, 'left to right'
// calculate the angle
const rad = Math.atan2(y, x);
let deg = rad * (180 / Math.PI);
// take into account if phone is held sideways / in landscape mode
const screenOrientation = screen.orientation;
// 90, -90, or 0
const angle = screenOrientation.angle || window.orientation || 0;
// now deg is <-180,180>
deg = Math.round(deg + angle);
// so if its negative, we will convert it to <180,360>
if (deg < 0) {
deg = 360 + deg;
}
if (exactAngle) {
return deg;
}
// should be 45 instead of 55, but its more preferable to keep default (portrait mode)
if (deg > 55 && deg <= 135) {
return 90;
}
if (deg > 135 && deg < 225) {
return 180;
}
// should be 315 instead of 305, but its more preferable to keep default (portrait mode)
if (deg >= 225 && deg < 305) {
return 270;
}
return 0;
}
/**
* @returns {Boolean} Returns true if device is in portrait mode, false otherwise
*/
export function isPortrait(event) {
const orientation = getDeviceOrientation(event);
return (orientation === 0 || orientation === 180);
}
/**
* @returns {Boolean} Returns true if device is in landscape (flipped to side) mode, false otherwise
*/
export function isLandscape(event) {
const orientation = getDeviceOrientation(event);
return (orientation === 90 || orientation === 270);
}
/**
* @returns {Boolean} Returns true if device is in standard portrait mode, false otherwise
*/
export function isPortraitDefault(event) {
return getDeviceOrientation(event) === 0;
}
/**
* @returns {Boolean} Returns true if device is in reverse portrait mode, false otherwise
*/
export function isPortraitReversed(event) {
return getDeviceOrientation(event) === 180;
}
/**
* @returns {Boolean} Returns true if device is in landscape (flipped to right side) position, false otherwise
*/
export function isLandscapeRight(event) {
return getDeviceOrientation(event) === 90;
}
/**
* @returns {Boolean} Returns true if device is in landscape (flipped to left side) position, false otherwise
*/
export function isLandscapeLeft(event) {
return getDeviceOrientation(event) === 270;
}
/**
* Sets `deviceorientation` listener for you, the last event will be cached, so you can call `getDeviceOrientation` without any parameter and the cached event will be used
*
* @param {Boolean} throwErrorIfNotSupported if sets to true, then it will throw an error if window.DeviceOrientationEvent is undefined
*/
export function init(throwErrorIfNotSupported = false) {
if (window.DeviceOrientationEvent === undefined) {
if (throwErrorIfNotSupported) {
throw new Error('DeviceOrientationEvent is not supported in current browser');
}
return;
}
window.addEventListener("deviceorientation", (event) => {
_deviceOrientation_cachedEvent = event;
}, true);
}
export default {
getDeviceOrientation,
isPortrait,
isLandscape,
isPortraitDefault,
isPortraitReversed,
isLandscapeRight,
isLandscapeLeft,
init,
};