OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 var vrShellUi = (function() { | |
6 'use strict'; | |
7 | |
8 /** | |
9 * Enumeration of valid Anchroing for X axis. | |
10 * A mesh can either be anchored to the left, right, or center of the main | |
11 * content rect (or it can be absolutely positioned using NONE). Any | |
12 * translations applied will be relative to this anchoring. | |
13 * @enum {number} | |
14 * @const | |
15 */ | |
16 var XAnchoring = Object.freeze({ | |
17 'XLEFT': 0, | |
18 'XRIGHT': 1, | |
19 'XCENTER': 2, | |
20 'XNONE': 3 | |
21 }); | |
22 | |
23 /** | |
24 * Enumeration of valid Anchroing for Y axis. | |
25 * @enum {number} | |
26 * @const | |
27 */ | |
28 var YAnchoring = Object.freeze({ | |
29 'YTOP': 0, | |
30 'YBOTTOM': 1, | |
31 'YCENTER': 2, | |
32 'YNONE': 3 | |
33 }); | |
34 | |
35 /** | |
36 * Enumeration of animatable properties. | |
37 * @enum {number} | |
38 * @const | |
39 */ | |
40 var Property = Object.freeze({ | |
41 'COPYRECT': 0, | |
42 'SIZE': 1, | |
43 'TRANSLATION': 2, | |
44 'ORIENTATION': 3, | |
45 'ROTATION': 4 | |
46 }); | |
47 | |
48 /** | |
49 * Enumeration of easing type. | |
50 * @enum {number} | |
51 * @const | |
52 */ | |
53 var Easing = Object.freeze({ | |
54 'LINEAR': 0, | |
55 'CUBICBEZIER': 1, | |
56 'EASEIN': 2, | |
57 'EASEOUT': 3 | |
58 }); | |
59 | |
60 /** | |
61 * @type {number} Id generator. | |
62 */ | |
63 var idIndex = 1; | |
64 | |
65 class UiElement { | |
66 /** | |
67 * Constructor of UiElement. | |
68 * pixelX and pixelY values indicate the left upper corner; pixelWidth and | |
69 * pixelHeight is width and height of the texture to be copied from the web | |
70 * contents. metersX and metersY indicate the size of the rectangle onto | |
71 * which the pixel region will be mapped. | |
72 */ | |
bshe
2016/09/15 22:02:11
I know I didn't quite follow closure jsdoc require
| |
73 constructor(pixelX, pixelY, pixelWidth, pixelHeight, metersX, metersY) { | |
74 this.copyRect = { | |
75 x: pixelX, | |
76 y: pixelY, | |
77 width: pixelWidth, | |
78 height: pixelHeight | |
79 }; | |
80 this.size = { x: metersX, y: metersY }; | |
81 this.xAnchoring = XAnchoring.XNONE; | |
82 this.yAnchoring = YAnchoring.YNONE; | |
83 this.anchorZ = false; | |
84 this.translation = { x: 0, y: 0, z: 0 }; | |
85 this.orientationAxisAngle = { x: 0, y: 0, z: 0, a: 0 }; | |
86 this.rotationAxisAngle = { x: 0, y: 0, z: 0, a: 0 }; | |
87 } | |
88 | |
89 /** | |
90 * The rotation for the mesh in 3D, applied before translation. The | |
91 * rotation is axis-angle representation (rotated around unit vector [x, y, | |
92 * z] by 'a' radians). | |
93 */ | |
94 setRotation(x, y, z, a) { | |
95 this.rotationAxisAngle = { x: x, y: y, z: z, a: a }; | |
96 } | |
97 | |
98 /** | |
99 * The offset for the mesh in 3D. If anchoring is specified, the offset is | |
100 * applied to the anchoring position rather than the origin. | |
101 */ | |
102 setTranslation(x, y, z) { | |
103 this.translation = { x: x, y: y, z: z }; | |
104 } | |
105 | |
106 /** | |
107 * Anchoring allows a rectangle to be positioned relative to the content | |
108 * window. X and Y values should be XAnchoring and YAnchoring elements. | |
109 * anchorZ is a boolean. | |
110 * Example: rect.setAnchoring(XAnchoring.XCENTER, YAnchoring.YBOTTOM, true); | |
111 */ | |
112 setAnchoring(x, y, z) { | |
113 this.xAnchoring = x; | |
114 this.yAnchoring = y; | |
115 this.anchorZ = z; | |
116 } | |
117 }; | |
118 | |
119 class Animation { | |
120 constructor(meshId, durationMs) { | |
121 this.meshId = meshId; | |
122 this.easing = {}; | |
123 this.from = {}; | |
124 this.to = {}; | |
125 this.easing.type = Easing.LINEAR; | |
126 | |
127 // How many milliseconds in the future to start the animation. | |
128 this.startInMillis = 0.0; | |
129 // Duration of the animation (milliseconds). | |
130 this.durationMillis = durationMs; | |
131 } | |
132 | |
133 setRotateTo(x, y, z, a) { | |
134 this.property = Property.ROTATION; | |
135 this.to.x = x; | |
136 this.to.y = y; | |
137 this.to.z = z; | |
138 this.to.a = a; | |
139 } | |
140 | |
141 setResizeTo(newWidth, newHeight) { | |
142 this.property = Property.SIZE; | |
143 this.to.x = newWidth; | |
144 this.to.y = newHeight; | |
145 } | |
146 }; | |
147 | |
148 function initialize() { | |
149 domLoaded(); | |
150 | |
151 // Change the body background so that the transparency applies. | |
152 window.setTimeout(function() { | |
153 document.body.parentNode.style.backgroundColor = 'rgba(255,255,255,0)'; | |
xiyuan
2016/09/15 22:58:47
Can this be in css to replace
rgba(255, 255, 255
bshe
2016/09/16 18:27:53
Had a quick chat with Micheal. It looks like this
| |
154 }, 100); | |
155 | |
156 addControlButtons(); | |
157 } | |
158 | |
159 // Build a row of control buttons. | |
160 function addControlButtons() { | |
161 var buttons = [ | |
162 // Button text, UI action passed down to native. | |
163 ['<', 'HISTORY_BACK'], | |
164 ['>', 'HISTORY_FORWARD'], | |
165 ['R', 'RELOAD'], | |
166 ['-', 'ZOOM_OUT'], | |
167 ['+', 'ZOOM_IN'] | |
168 ]; | |
169 | |
170 var buttonWidth = 0.3; | |
171 var buttonHeight = 0.2; | |
172 var buttonSpacing = 0.5; | |
173 var buttonStartPosition = -buttonSpacing * (buttons.length / 2.0 - 0.5); | |
174 | |
175 for (var i = 0; i < buttons.length; i++) { | |
176 var b = document.createElement('div'); | |
177 b.position = 'absolute'; | |
178 b.style.top = '200px'; | |
179 b.style.left = 50 * i + 'px'; | |
180 b.style.width = '50px'; | |
181 b.style.height = '50px'; | |
182 b.className = 'ui-button'; | |
183 b.innerHTML = buttons[i][0]; | |
xiyuan
2016/09/15 22:58:47
nit: innerHTML -> textContent ?
bshe
2016/09/16 18:27:53
Done.
| |
184 | |
185 // Add click behaviour. | |
186 b.addEventListener('click', function(action, e) { | |
187 chrome.send('doAction', [action]); | |
188 }.bind(undefined, buttons[i][1])); | |
189 | |
190 document.body.appendChild(b); | |
191 | |
192 // Add a UI rectangle for the button. | |
193 var el1 = new UiElement(50 * i, 200, 50, 50, buttonWidth, buttonHeight); | |
xiyuan
2016/09/15 22:58:47
nit: why el1? Would there be an el2? If not, we sh
bshe
2016/09/16 18:27:53
Done.
| |
194 el1.setAnchoring(XAnchoring.XCENTER, YAnchoring.YBOTTOM, true); | |
195 el1.setTranslation(buttonStartPosition + buttonSpacing * i, -0.3, 0.0); | |
196 var id = idIndex++; | |
197 addMesh(id, el1); | |
198 | |
199 // Add transitions when the mouse hovers over (and leaves) the button. | |
200 b.addEventListener('mouseenter', function(buttonId, width, height, e) { | |
201 var resize = new Animation(buttonId, 250); | |
202 resize.id = idIndex++; | |
203 resize.setResizeTo(width, height); | |
204 chrome.send('addAnimations', [resize]); | |
205 }.bind(undefined, id, buttonWidth * 1.5, buttonHeight * 1.5)); | |
206 b.addEventListener('mouseleave', function(buttonId, width, height) { | |
207 var resize = new Animation(buttonId, 250); | |
208 resize.id = idIndex++; | |
209 resize.setResizeTo(width, height); | |
210 chrome.send('addAnimations', [resize]); | |
211 }.bind(undefined, id, buttonWidth, buttonHeight)); | |
212 } | |
213 } | |
214 | |
215 function domLoaded() { | |
216 chrome.send('domLoaded', [window.innerWidth, window.innerHeight]); | |
217 } | |
218 | |
219 function addAnimations(animations) { | |
220 chrome.send('addAnimations', animations); | |
221 } | |
222 | |
223 function addMesh(id, mesh) { | |
224 chrome.send('addMesh', [id, mesh]); | |
225 } | |
226 | |
227 function removeMesh(id) { | |
xiyuan
2016/09/15 22:58:47
nit: seems not used.
bshe
2016/09/16 18:27:52
Done.
| |
228 chrome.send('removeMesh', [id]); | |
229 } | |
230 | |
231 return { | |
232 initialize: initialize, | |
233 }; | |
234 })(); | |
235 | |
236 document.addEventListener('DOMContentLoaded', vrShellUi.initialize); | |
OLD | NEW |