| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 var vrShellUi = (function() { | 5 var vrShellUi = (function() { |
| 6 'use strict'; | 6 'use strict'; |
| 7 | 7 |
| 8 /** | 8 var scene = new ui.Scene(); |
| 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 'XNONE': 0, | |
| 18 'XLEFT': 1, | |
| 19 'XRIGHT': 2 | |
| 20 }); | |
| 21 | |
| 22 /** | |
| 23 * Enumeration of valid Anchroing for Y axis. | |
| 24 * @enum {number} | |
| 25 * @const | |
| 26 */ | |
| 27 var YAnchoring = Object.freeze({ | |
| 28 'YNONE': 0, | |
| 29 'YTOP': 1, | |
| 30 'YBOTTOM': 2 | |
| 31 }); | |
| 32 | |
| 33 /** | |
| 34 * Enumeration of animatable properties. | |
| 35 * @enum {number} | |
| 36 * @const | |
| 37 */ | |
| 38 var Property = Object.freeze({ | |
| 39 'COPYRECT': 0, | |
| 40 'SIZE': 1, | |
| 41 'TRANSLATION': 2, | |
| 42 'ORIENTATION': 3, | |
| 43 'ROTATION': 4 | |
| 44 }); | |
| 45 | |
| 46 /** | |
| 47 * Enumeration of easing type. | |
| 48 * @enum {number} | |
| 49 * @const | |
| 50 */ | |
| 51 var Easing = Object.freeze({ | |
| 52 'LINEAR': 0, | |
| 53 'CUBICBEZIER': 1, | |
| 54 'EASEIN': 2, | |
| 55 'EASEOUT': 3 | |
| 56 }); | |
| 57 | |
| 58 /** | |
| 59 * Enumeration of scene update commands. | |
| 60 * @enum {number} | |
| 61 * @const | |
| 62 */ | |
| 63 var Command = Object.freeze({ | |
| 64 'ADD_ELEMENT': 0, | |
| 65 'UPDATE_ELEMENT': 1, | |
| 66 'REMOVE_ELEMENT': 2, | |
| 67 'ADD_ANIMATION': 3, | |
| 68 'REMOVE_ANIMATION': 4 | |
| 69 }); | |
| 70 | |
| 71 /** | |
| 72 * @type {number} Id generator. | |
| 73 */ | |
| 74 var idIndex = 1; | |
| 75 | |
| 76 class UiElement { | |
| 77 /** | |
| 78 * Constructor of UiElement. | |
| 79 * pixelX and pixelY values indicate the left upper corner; pixelWidth and | |
| 80 * pixelHeight is width and height of the texture to be copied from the web | |
| 81 * contents. metersX and metersY indicate the size of the rectangle onto | |
| 82 * which the pixel region will be mapped. | |
| 83 */ | |
| 84 constructor(pixelX, pixelY, pixelWidth, pixelHeight, metersX, metersY) { | |
| 85 this.copyRect = { | |
| 86 x: pixelX, | |
| 87 y: pixelY, | |
| 88 width: pixelWidth, | |
| 89 height: pixelHeight | |
| 90 }; | |
| 91 this.size = { x: metersX, y: metersY }; | |
| 92 this.xAnchoring = XAnchoring.XNONE; | |
| 93 this.yAnchoring = YAnchoring.YNONE; | |
| 94 this.translation = { x: 0, y: 0, z: 0 }; | |
| 95 this.orientationAxisAngle = { x: 0, y: 0, z: 0, a: 0 }; | |
| 96 this.rotationAxisAngle = { x: 0, y: 0, z: 0, a: 0 }; | |
| 97 } | |
| 98 | |
| 99 /** | |
| 100 * The rotation for the mesh in 3D, applied before translation. The | |
| 101 * rotation is axis-angle representation (rotated around unit vector [x, y, | |
| 102 * z] by 'a' radians). | |
| 103 */ | |
| 104 setRotation(x, y, z, a) { | |
| 105 this.rotationAxisAngle = { x: x, y: y, z: z, a: a }; | |
| 106 } | |
| 107 | |
| 108 /** | |
| 109 * The offset for the mesh in 3D. If anchoring is specified, the offset is | |
| 110 * applied to the anchoring position rather than the origin. | |
| 111 */ | |
| 112 setTranslation(x, y, z) { | |
| 113 this.translation = { x: x, y: y, z: z }; | |
| 114 } | |
| 115 | |
| 116 /** | |
| 117 * Anchoring allows a rectangle to be positioned relative to the edge of | |
| 118 * content window. Values should be XAnchoring and YAnchoring elements. | |
| 119 * Example: rect.setAnchoring(XAnchoring.XNONE, YAnchoring.YBOTTOM); | |
| 120 */ | |
| 121 setAnchoring(x, y, z) { | |
| 122 this.xAnchoring = x; | |
| 123 this.yAnchoring = y; | |
| 124 } | |
| 125 }; | |
| 126 | |
| 127 class Animation { | |
| 128 constructor(meshId, durationMs) { | |
| 129 this.meshId = meshId; | |
| 130 this.easing = {}; | |
| 131 this.to = {}; | |
| 132 this.easing.type = Easing.LINEAR; | |
| 133 | |
| 134 // How many milliseconds in the future to start the animation. | |
| 135 this.startInMillis = 0.0; | |
| 136 // Duration of the animation (milliseconds). | |
| 137 this.durationMillis = durationMs; | |
| 138 } | |
| 139 | |
| 140 setRotateTo(x, y, z, a) { | |
| 141 this.property = Property.ROTATION; | |
| 142 this.to.x = x; | |
| 143 this.to.y = y; | |
| 144 this.to.z = z; | |
| 145 this.to.a = a; | |
| 146 } | |
| 147 | |
| 148 setResizeTo(newWidth, newHeight) { | |
| 149 this.property = Property.SIZE; | |
| 150 this.to.x = newWidth; | |
| 151 this.to.y = newHeight; | |
| 152 } | |
| 153 }; | |
| 154 | 9 |
| 155 function initialize() { | 10 function initialize() { |
| 11 |
| 156 domLoaded(); | 12 domLoaded(); |
| 157 | 13 |
| 158 // Change the body background so that the transparency applies. | 14 // Change the body background so that the transparency applies. |
| 159 window.setTimeout(function() { | 15 window.setTimeout(function() { |
| 160 document.body.parentNode.style.backgroundColor = 'rgba(255,255,255,0)'; | 16 document.body.parentNode.style.backgroundColor = 'rgba(255,255,255,0)'; |
| 161 }, 100); | 17 }, 100); |
| 162 | 18 |
| 163 addControlButtons(); | 19 addControlButtons(); |
| 164 } | 20 } |
| 165 | 21 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 184 b.position = 'absolute'; | 40 b.position = 'absolute'; |
| 185 b.style.top = '200px'; | 41 b.style.top = '200px'; |
| 186 b.style.left = 50 * i + 'px'; | 42 b.style.left = 50 * i + 'px'; |
| 187 b.style.width = '50px'; | 43 b.style.width = '50px'; |
| 188 b.style.height = '50px'; | 44 b.style.height = '50px'; |
| 189 b.className = 'ui-button'; | 45 b.className = 'ui-button'; |
| 190 b.textContent = buttons[i][0]; | 46 b.textContent = buttons[i][0]; |
| 191 | 47 |
| 192 // Add click behaviour. | 48 // Add click behaviour. |
| 193 b.addEventListener('click', function(action, e) { | 49 b.addEventListener('click', function(action, e) { |
| 194 chrome.send('doAction', [action]); | 50 api.doAction(action); |
| 195 }.bind(undefined, buttons[i][1])); | 51 }.bind(undefined, buttons[i][1])); |
| 196 | 52 |
| 197 document.body.appendChild(b); | 53 document.body.appendChild(b); |
| 198 | 54 |
| 199 // Add a UI rectangle for the button. | 55 // Add a UI rectangle for the button. |
| 200 var el = new UiElement(50 * i, 200, 50, 50, buttonWidth, buttonHeight); | 56 var el = new api.UiElement(50 * i, 200, 50, 50); |
| 201 el.parentId = 0; | 57 el.setParentId(api.getContentElementId()); |
| 202 el.setAnchoring(XAnchoring.XNONE, YAnchoring.YBOTTOM); | 58 el.setAnchoring(api.XAnchoring.XNONE, api.YAnchoring.YBOTTOM); |
| 59 el.setSize(buttonWidth, buttonHeight); |
| 203 el.setTranslation(buttonStartPosition + buttonSpacing * i, -0.3, 0.0); | 60 el.setTranslation(buttonStartPosition + buttonSpacing * i, -0.3, 0.0); |
| 204 var id = idIndex++; | 61 var buttonId = scene.addElement(el); |
| 205 addMesh(id, el); | |
| 206 | 62 |
| 207 // Add transitions when the mouse hovers over (and leaves) the button. | 63 // Add transitions when the mouse hovers over (and leaves) the button. |
| 208 b.addEventListener('mouseenter', function(buttonId, width, height, e) { | 64 b.addEventListener('mouseenter', function(buttonId, width, height, e) { |
| 209 var resize = new Animation(buttonId, 250); | 65 var resize = new api.Animation(buttonId, 250); |
| 210 resize.id = idIndex++; | 66 resize.setSize(width, height); |
| 211 resize.setResizeTo(width, height); | 67 scene.addAnimation(resize); |
| 212 addAnimations([resize]); | 68 scene.flush(); |
| 213 }.bind(undefined, id, buttonWidth * 1.5, buttonHeight * 1.5)); | 69 }.bind(undefined, buttonId, buttonWidth * 1.5, buttonHeight * 1.5)); |
| 214 b.addEventListener('mouseleave', function(buttonId, width, height) { | 70 b.addEventListener('mouseleave', function(buttonId, width, height) { |
| 215 var resize = new Animation(buttonId, 250); | 71 var resize = new api.Animation(buttonId, 250); |
| 216 resize.id = idIndex++; | 72 resize.setSize(width, height); |
| 217 resize.setResizeTo(width, height); | 73 scene.addAnimation(resize); |
| 218 addAnimations([resize]); | 74 scene.flush(); |
| 219 }.bind(undefined, id, buttonWidth, buttonHeight)); | 75 }.bind(undefined, buttonId, buttonWidth, buttonHeight)); |
| 220 } | 76 } |
| 77 scene.flush(); |
| 221 } | 78 } |
| 222 | 79 |
| 223 function domLoaded() { | 80 function domLoaded() { |
| 224 chrome.send('domLoaded', [window.innerWidth, window.innerHeight]); | 81 api.domLoaded(window.innerWidth, window.innerHeight); |
| 225 } | |
| 226 | |
| 227 function addMesh(id, mesh) { | |
| 228 mesh.id = id; | |
| 229 chrome.send('updateScene', [{ | |
| 230 'type': Command.ADD_ELEMENT, | |
| 231 'data': mesh | |
| 232 }]); | |
| 233 } | |
| 234 | |
| 235 function removeMesh(id) { | |
| 236 chrome.send('updateScene', [{ | |
| 237 'type': Command.REMOVE_ELEMENT, | |
| 238 'data': {'id': id} | |
| 239 }]); | |
| 240 } | |
| 241 | |
| 242 function addAnimations(animations) { | |
| 243 var commands = []; | |
| 244 for (var i = 0; i < animations.length; i++) { | |
| 245 commands.push({ | |
| 246 'type': Command.ADD_ANIMATION, | |
| 247 'data': animations[i] | |
| 248 }); | |
| 249 } | |
| 250 chrome.send('updateScene', commands); | |
| 251 } | 82 } |
| 252 | 83 |
| 253 return { | 84 return { |
| 254 initialize: initialize, | 85 initialize: initialize, |
| 255 }; | 86 }; |
| 256 })(); | 87 })(); |
| 257 | 88 |
| 258 document.addEventListener('DOMContentLoaded', vrShellUi.initialize); | 89 document.addEventListener('DOMContentLoaded', vrShellUi.initialize); |
| OLD | NEW |