├── COPYING ├── readme.md ├── index.html └── assets ├── css └── site.css └── js └── device.js /COPYING: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Device Orientation - 3d 2 | 3 | ## Post 4 | 5 | - [https://f90.co.uk/labs/device-orientation-3d/](https://f90.co.uk/labs/device-orientation-3d/) 6 | 7 | ## Example 8 | 9 | - [http://orangespaceman.github.io/device-orientation-3d](http://orangespaceman.github.io/device-orientation-3d) 10 | 11 | Copyright © 2018 Me 12 | This work is free. You can redistribute it and/or modify it under the 13 | terms of the Do What The Fuck You Want To Public License, Version 2, 14 | as published by Sam Hocevar. See the COPYING file for more details. 15 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Device Orientation - 3d 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 | -------------------------------------------------------------------------------- /assets/css/site.css: -------------------------------------------------------------------------------- 1 | /* elements */ 2 | 3 | *, 4 | *:before, 5 | *:after { 6 | box-sizing: border-box; 7 | } 8 | 9 | html { 10 | font-size: 16px; 11 | height: 100%; 12 | width: 100%; 13 | } 14 | 15 | body { 16 | background: #506080; 17 | font-family: Georgia, serif; 18 | height: 100%; 19 | margin: 0; 20 | width: 100%; 21 | } 22 | 23 | /* Wrapper */ 24 | 25 | .Wrapper { 26 | height: 100vh; 27 | width: 100vw; 28 | overflow: hidden; 29 | 30 | display: flex; 31 | align-items: center; 32 | justify-content: center; 33 | } 34 | 35 | /* 3d */ 36 | 37 | .Scene { 38 | background: rgba(0,0,0,0.1); 39 | box-shadow: 0 0 25px 0 rgba(0,0,0,0.1); 40 | position: relative; 41 | margin: 0 auto; 42 | width: 50vw; 43 | height: 60vh; 44 | perspective: 1000px; 45 | transform: translate(0); 46 | } 47 | 48 | .Device { 49 | transform-style: preserve-3d; 50 | transform-origin: 25vw 30vh; 51 | } 52 | 53 | .Device > * { 54 | position: absolute; 55 | } 56 | 57 | .Device-front { 58 | width: 50vw; 59 | height: 60vh; 60 | background: #f90; 61 | transform: translateX(0) rotateY(0deg) translateZ(15px); 62 | } 63 | 64 | .Device-back { 65 | width: 50vw; 66 | height: 60vh; 67 | background: #f60; 68 | transform: translateX(0) translateZ(-15px); 69 | } 70 | 71 | .Device-left { 72 | width: 30px; 73 | height: 60vh; 74 | background: #f30; 75 | transform: translateX(-15px) rotateY(-90deg); 76 | backface-visibility: hidden; 77 | } 78 | 79 | .Device-right { 80 | width: 30px; 81 | height: 60vh; 82 | background: #f30; 83 | transform: translateX(calc(50vw - 15px)) rotateY(90deg); 84 | backface-visibility: hidden; 85 | } 86 | 87 | .Device-top { 88 | width: 50vw; 89 | height: 30px; 90 | background: #f30; 91 | transform: rotateX(90deg) translateZ(15px); 92 | backface-visibility: hidden; 93 | } 94 | 95 | .Device-bottom { 96 | width: 50vw; 97 | height: 30px; 98 | background: #f30; 99 | transform: rotateX(-90deg) translateZ(calc(60vh - 15px)); 100 | backface-visibility: hidden; 101 | } 102 | 103 | /* debug */ 104 | 105 | .Debug { 106 | display: flex; 107 | justify-content: space-around; 108 | position: fixed; 109 | top: 0; 110 | right: 0; 111 | left: 0; 112 | background: rgba(255, 255, 255, 0.4); 113 | padding: 0.2rem; 114 | z-index: 3; 115 | font-size: 0.75rem; 116 | text-align: left; 117 | opacity: 1; 118 | } 119 | 120 | .Debug-block { 121 | margin: 0; 122 | } -------------------------------------------------------------------------------- /assets/js/device.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // device orientation - default to portrait 4 | var isLandscape = false; 5 | var isRotatedClockwise = false; 6 | 7 | // device el 8 | var device = document.querySelector('.Device'); 9 | 10 | // debug els 11 | var debugAlphaEl = document.querySelector('.Debug-value--alpha'); 12 | var debugBetaEl = document.querySelector('.Debug-value--beta'); 13 | var debugGammaEl = document.querySelector('.Debug-value--gamma'); 14 | var debugAlphaModifiedEl = document.querySelector('.Debug-value--alphaModified'); 15 | var debugBetaModifiedEl = document.querySelector('.Debug-value--betaModified'); 16 | var debugGammaModifiedEl = document.querySelector('.Debug-value--gammaModified'); 17 | 18 | // recalculate values based on major device rotation 19 | // (e.g. landscape to portrait or vice versa) 20 | // allow time for the screen layout to readjust first 21 | function handleOrientationChange() { 22 | setTimeout(function() { 23 | calculateDeviceOrientation(); 24 | }, 500); 25 | } 26 | 27 | // calculate whether the device is landscape or portrait 28 | function calculateDeviceOrientation(e) { 29 | isLandscape = 30 | document.documentElement.clientHeight < document.documentElement.clientWidth; 31 | isRotatedClockwise = window.orientation === -90; 32 | } 33 | 34 | // update display on device orientation 35 | function handleDeviceorientationEvent(e) { 36 | var alpha = normaliseAlpha(e); 37 | var beta = normaliseBeta(e); 38 | var gamma = normaliseGamma(e); 39 | 40 | render(alpha, beta, gamma); 41 | debug(alpha, beta, gamma, e); 42 | } 43 | 44 | // update device 45 | function render(alpha, beta, gamma) { 46 | device.style.transform = 47 | "rotateX(" + beta + "deg) " + 48 | "rotateY(" + gamma + "deg) " + 49 | "rotateZ(" + alpha + "deg)"; 50 | } 51 | 52 | function normaliseAlpha(e) { 53 | var alpha; 54 | if (!isLandscape) { 55 | if (e.beta > 90) { 56 | alpha = e.alpha - 90; 57 | } else { 58 | alpha = -e.alpha + 90; 59 | } 60 | } else { 61 | if (isRotatedClockwise) { 62 | if (Math.abs(e.beta) > 90) { 63 | alpha = e.alpha; 64 | } else { 65 | alpha = -e.alpha; 66 | } 67 | } else { 68 | if (Math.abs(e.beta) > 90) { 69 | alpha = e.alpha; 70 | } else { 71 | alpha = -e.alpha; 72 | } 73 | } 74 | } 75 | return alpha; 76 | } 77 | 78 | function normaliseBeta(e) { 79 | var beta; 80 | if (!isLandscape) { 81 | beta = (-e.beta + 90); 82 | } else { 83 | if (isRotatedClockwise) { 84 | beta = (-e.gamma + 90); 85 | } else { 86 | beta = 90 + e.gamma; 87 | } 88 | } 89 | return beta; 90 | } 91 | 92 | function normaliseGamma(e) { 93 | var gamma; 94 | if (!isLandscape) { 95 | gamma = e.gamma; 96 | } else { 97 | if (isRotatedClockwise) { 98 | if (Math.abs(e.beta) > 90) { 99 | gamma = e.beta; 100 | } else { 101 | gamma = (-e.beta); 102 | } 103 | } else { 104 | if (Math.abs(e.beta) > 90) { 105 | gamma = (-e.beta); 106 | } else { 107 | gamma = e.beta; 108 | } 109 | } 110 | } 111 | return gamma; 112 | } 113 | 114 | function debug(alpha, beta, gamma, e) { 115 | debugAlphaEl.textContent = Math.round(e.alpha); 116 | debugBetaEl.textContent = Math.round(e.beta); 117 | debugGammaEl.textContent = Math.round(e.gamma); 118 | debugAlphaModifiedEl.textContent = Math.round(alpha); 119 | debugBetaModifiedEl.textContent = Math.round(beta); 120 | debugGammaModifiedEl.textContent = Math.round(gamma); 121 | } 122 | 123 | // init 124 | calculateDeviceOrientation(); 125 | window.addEventListener('orientationchange', handleOrientationChange); 126 | window.addEventListener("deviceorientation", handleDeviceorientationEvent); 127 | 128 | })(); 129 | --------------------------------------------------------------------------------