├── 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 |
--------------------------------------------------------------------------------