├── .gitattributes ├── QUIRKS.md ├── README.md ├── cube.html ├── gyro.js ├── gyro.min.js └── index.html /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /QUIRKS.md: -------------------------------------------------------------------------------- 1 | Gyroscope 2 | ========= 3 | 4 | Measures device's rotation around 3 axis 5 | 6 | Portrait mode: 7 | -------------- 8 | 9 | ``` 10 | 11 | Front view Top view 12 | _______ 13 | | _____ | +---> beta 14 | || || | axis 15 | || || v 16 | || || alpha ___________ 17 | || || axis |___________| +----> beta 18 | || || \\‾‾‾‾‾‾‾// | axis 19 | || || \\_____// v 20 | || || \__o__/ gamma 21 | ||_____|| axis 22 | |___o___| 23 | 24 | 25 | ``` 26 | 27 | Landscape mode (left): 28 | ---------------------- 29 | 30 | ``` 31 | 32 | Front view Top view 33 | _______________ _______________ 34 | | ____________ | +---> gamma |_______________| +----> gamma axis 35 | || | | | axis \ ========= o / | (reversed) 36 | || |o| v ‾‾‾‾‾‾‾‾‾‾‾‾‾ v 37 | ||____________| | alpha beta 38 | |_______________| axis axis 39 | 40 | 41 | ``` 42 | 43 | Landscape mode (right): 44 | ---------------------- 45 | 46 | ``` 47 | 48 | Front view Top view 49 | _______________ _______________ 50 | | ____________ | +---> gamma |_______________| +----> gamma 51 | | | || | axis \ o ========= / | axis 52 | |o| || v ‾‾‾‾‾‾‾‾‾‾‾‾‾ v 53 | | |____________|| alpha beta 54 | |_______________| axis axis 55 | 56 | 57 | ``` 58 | 59 | - Alpha should be 0 on load (but it is not reliable on all devices). 60 | Rotate to your left: value increases. Rotate to your right: value decreases. 61 | Value loops between 0 and 360. 62 | 63 | In landscape mode: 64 | 65 | - Beta has values between 180 and -180 (90 to -90 on Safari mobile). 66 | Value = 0 when the device is held vertically. Tilt to your left: value decreases. Tilt to your right: value increases. 67 | 68 | - Gamma is between 90 and -90 (180 to -180 on Safari mobile). 69 | When the device is held vertically: value = 90 = -90. when screen is facing up/down: value reaches ±0. 70 | (Portrait mode: facing up = 90 to 0. Landscape left: facing up = -90 to -0. Landscape right: facing up = 90 to 0.) 71 | 72 | In portrait mode, beta and gamma are interchanged. 73 | 74 | - By default, measures are "relative" (i.e. done along the device's X/Y/Z axis). 75 | Chrome < 50 did absolute measures by default, and can still do them using the non-standard event ondeviceorientationabsolute. 76 | 77 | 78 | Accelerometer 79 | ============= 80 | 81 | Measures the device's acceleration, but along the world's X/Y/Z axis. 82 | (moving the phone "up" in the air will update the up/down acceleration axis, whatever the angle of the phone) 83 | 84 | - accelerationIncludingGravity.x / y / z include earth's gravity. 85 | - acceleration.x / y / z shouldn't include Earth's gravity (some old devices still do). 86 | - Earth's gravity is measured as a positive or negative number (~10 m/s²) depending on the devices and their orientation. 87 | - On some devices, the object returned by the ondevicemotion event doesn't contain some expected fields like acceleration. 88 | 89 | In portrait mode: 90 | 91 | - x: 0 if immobile. Negative if moving right. Positive if moving left. 92 | - y: 0 if immobile. Negative if moving up. Positive if moving down. 93 | - z: 0 if immobile. Negative if moving front. Positive if moving back. 94 | 95 | In landscape left mode: 96 | 97 | - x: 0 if immobile. Negative if moving front. Positive if moving back. 98 | - y: 0 if immobile. Negative if moving right. Positive if moving right. 99 | - z: 0 if immobile. Negative if moving up. Positive if moving down. 100 | 101 | In landscape right mode: 102 | 103 | - x: 0 if immobile. Negative if moving back. Positive if moving front. 104 | - y: 0 if immobile. Negative if moving right. Positive if moving left. 105 | - z: 0 if immobile. Negative if moving down. Positive if moving up. 106 | 107 | 108 | Interesting reads: 109 | ================== 110 | - http://www.asterixcreative.com/blog/mobile-gyroscope-with-javascript-and-quaternions-programming-tutorial-part-1/ 111 | - https://dev.opera.com/articles/w3c-device-orientation-usage/ 112 | - Gyronorm.js documentation 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | What Gyro.js does: 2 | ================== 3 | 4 | - listens for deviceorientation and devicemotion events
5 | - converts and adjusts the measured values so they are the same for every orientation (portrait, landscape
left, landscape right)
6 | - updates a `gyro` object with 7 attributes that you can read at any given time: 7 | - Android only (iOS support coming soon) 8 | 9 | orientation: 10 | ------------ 11 | 12 | 0 : portrait, 13 | 90: landscape left, 14 | -90: landscape right. 15 | 16 | alpha: 17 | ------ 18 | 19 | value = 0 on load,
20 | values up to 180 by rotating on your left and down to -180 by rotating on your right. 21 | 22 | beta: 23 | ----- 24 | 25 | value: 0 when standing vertically,
26 | values down to -90 when the screen is facing down, up to 90 when it's facing up,
27 | whatever the value of gyro.orientation is. 28 | 29 | gamma: 30 | ------ 31 | 32 | value: 0 when standng vertically,
33 | values up to 180 by tilting the device on the left and down to -180 by tilting on the right,
34 | whatever the value of gyro.orientation is. 35 | 36 | x: 37 | -- 38 | 39 | acceleration along the axis from your front (positive values) to your back (negative values),
40 | whatever the value of alpha, beta and gamma are. 41 | 42 | y: 43 | -- 44 | 45 | acceleration along the axis from your left (positive values) to your right (negative values),
46 | whatever the value of alpha, beta and gamma are. 47 | 48 | z: 49 | -- 50 | 51 | acceleration along the axis from your up (positive values) to your down (negative values),
52 | whatever the value of alpha, beta and gamma are. 53 | 54 | --- 55 | 56 | *Note* 57 | 58 | The values returned for alpha, beta and gamma are non-standard (specific to Gyro.js).
59 | I've put them this way to make them more dev-friendly.
60 | (see QUIRKS.md for more details about native values) 61 | 62 | --- 63 | 64 | *Note 2* 65 | 66 | Gyro.js is < 700b minified, promise-less, and ES6-less.
67 | For more features and less value harmonization, take a look at Full-Tilt + Gyronorm.js (18.1kb minified) -------------------------------------------------------------------------------- /cube.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 16 |
17 |
18 | 19 |
20 | 21 |
22 |

23 |

24 |

25 |

26 |

27 |

28 |

29 | 30 |
31 |
32 |
33 | 34 | 44 | -------------------------------------------------------------------------------- /gyro.js: -------------------------------------------------------------------------------- 1 | // Gyro 2 | // ==== 3 | 4 | // Global object gathering all the gyro/accelerometer data. 5 | gyro = { 6 | 7 | // Device orientation, not available on load but updated as soon as possible. 8 | orientation: null, 9 | 10 | // Alpha on load should be 0. 11 | // If it's not, it's set to 0 and the difference is saved in alpha0 to adjust all the following measures. 12 | alpha0: null, 13 | 14 | // iOS detection 15 | iOS: /iPad|iPhone|iPod/.test(navigator.userAgent) 16 | 17 | }; 18 | 19 | // gyro event 20 | // ========== 21 | 22 | ondeviceorientation = function(e){ 23 | 24 | // Orientation: 25 | // ------------ 26 | 27 | // Just in case it's not set by onorientationchange, set it again. 28 | if(gyro.orientation === null){ 29 | gyro.orientation = window.orientation || 0; 30 | } 31 | 32 | // Alpha: 33 | // ------ 34 | 35 | // On load, ensure alpha is 0. 36 | if(gyro.alpha0 === null){ 37 | gyro.alpha0 = e.alpha; 38 | } 39 | 40 | gyro.alpha = e.alpha - gyro.alpha0; 41 | 42 | // Set alpha between -180 and 180. 43 | if(gyro.alpha > 180){ 44 | gyro.alpha -= 360; 45 | } 46 | 47 | // Save raw beta and gamma values. 48 | var tempbeta = e.beta, tempgamma = e.gamma; 49 | 50 | // Fix iOS's beta (values are twice too small) and gamma (values are twice too big). 51 | if(gyro.iOS){ 52 | tempbeta *= 2; 53 | tempgamma <= 2; 54 | } 55 | 56 | // Beta & gamma: 57 | // ------------- 58 | 59 | // Portrait mode 60 | 61 | if(gyro.orientation == 0){ 62 | 63 | // Native beta value: 64 | // - When held vertically, value = 90. 65 | // - When screen facing up: 90 to 0. 66 | // - When screen facing down: 90 to 180. 67 | 68 | // New beta value: 69 | // - When held vertically, value = 0. 70 | // - When screen facing up: 0 to 90. 71 | // - When screen facing down: -0 to -90. 72 | gyro.beta = -tempbeta + 90; 73 | 74 | // Native gamma value: 75 | // - When held vertically, value = 0. 76 | // - When tilting to your left: -0 to -180. 77 | // - When tilting to your right: 0 to 180. 78 | 79 | // New gamma value 80 | // - When tilting to your left: 0 to 180. 81 | // - When tilting to your right: -0 to -180. 82 | 83 | gyro.gamma = -tempgamma; 84 | } 85 | 86 | // Landscape left mode 87 | 88 | else if(gyro.orientation == 90){ 89 | 90 | // Native *gamma* value: 91 | // - When held vertically, value = 90 = -90. 92 | // - When screen facing up: -90 to -0. 93 | // - When screen facing down: 90 to 0. 94 | 95 | // New *beta* value: 96 | // - When held vertically, value = 0. 97 | // - When screen facing up: 0 to 90. 98 | // - When screen facing down: -0 to -90. 99 | if(tempgamma < 0){ 100 | gyro.beta = 90 + tempgamma; 101 | } 102 | 103 | else { 104 | gyro.beta = tempgamma - 90; 105 | } 106 | 107 | // Native *beta* value: 108 | // - When held vertically, value = 0. 109 | // - When tilting to your left: -0 to -180. 110 | // - When tilting to your right: 0 to 180. 111 | 112 | // New *gamma* value 113 | // - When tilting to your left: 0 to 180. 114 | // - When tilting to your right: -0 to -180. 115 | 116 | gyro.gamma = -tempbeta; 117 | } 118 | 119 | // Landscape right mode 120 | 121 | else if(gyro.orientation == -90){ 122 | 123 | // Native *gamma* value: 124 | // - When held vertically, value = 90 = -90. 125 | // - When screen facing up: 90 to 0. 126 | // - When screen facing down: -90 to -0. 127 | 128 | // New *beta* value: 129 | // - When held vertically, value = 0. 130 | // - When screen facing up: 0 to 90. 131 | // - When screen facing down: -0 to -90. 132 | 133 | if(tempgamma < 0){ 134 | gyro.beta = -90 - tempgamma; 135 | } 136 | 137 | else { 138 | gyro.beta = 90 - tempgamma; 139 | } 140 | 141 | // Native *beta* value: 142 | // - When held vertically, value = 0. 143 | // - When tilting to your left: -0 to -180. 144 | // - When tilting to your right: 0 to 180. 145 | 146 | // New *gamma* value 147 | // - When tilting to your left: 0 to 180. 148 | // - When tilting to your right: -0 to -180. 149 | gyro.gamma = -tempbeta; 150 | 151 | } 152 | } 153 | 154 | // accelero event 155 | ondevicemotion = function(e){ 156 | 157 | // x: 158 | // -- 159 | 160 | gyro.x = e.acceleration.x; 161 | 162 | // y: 163 | // -- 164 | 165 | gyro.y = e.acceleration.y; 166 | 167 | // z: 168 | // -- 169 | 170 | gyro.z = e.acceleration.z; 171 | } 172 | 173 | // Change orientation 174 | // ------------------ 175 | 176 | onorientationchange = function() { 177 | gyro.orientation = window.orientation; 178 | } -------------------------------------------------------------------------------- /gyro.min.js: -------------------------------------------------------------------------------- 1 | gyro={orientation:null,alpha0:null,iOS:/iPad|iPhone|iPod/.test(navigator.userAgent)};ondeviceorientation=function(a){null===gyro.orientation&&(gyro.orientation=window.orientation||0);null===gyro.alpha0&&(gyro.alpha0=a.alpha);gyro.alpha=a.alpha-gyro.alpha0;180=a);0==gyro.orientation?(gyro.beta=-b+90,gyro.gamma=-a):90==gyro.orientation?(gyro.beta=0>a?90+a:a-90,gyro.gamma=-b):-90==gyro.orientation&&(gyro.beta=0>a?-90-a:90-a,gyro.gamma=-b)};ondevicemotion=function(a){gyro.x=a.acceleration.x;gyro.y=a.acceleration.y;gyro.z=a.acceleration.z};onorientationchange=function(){gyro.orientation=window.orientation} -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 29 |