Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1324)

Side by Side Diff: chrome/browser/resources/vr_shell/vr_shell_ui.js

Issue 2698033002: PROTOTYPE: Generic custom CSS property parsing (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 let ui = new scene.Scene(); 8 let ui = new scene.Scene();
9 let uiManager; 9 let uiManager;
10 let nativeCommandHandler; 10 let nativeCommandHandler;
(...skipping 24 matching lines...) Expand all
35 /** @const */ this.CSS_WIDTH_PIXELS = 960.0; 35 /** @const */ this.CSS_WIDTH_PIXELS = 960.0;
36 /** @const */ this.CSS_HEIGHT_PIXELS = 640.0; 36 /** @const */ this.CSS_HEIGHT_PIXELS = 640.0;
37 /** @const */ this.DPR = 1.2; 37 /** @const */ this.DPR = 1.2;
38 /** @const */ this.MENU_MODE_SCREEN_DISTANCE = 1.2; 38 /** @const */ this.MENU_MODE_SCREEN_DISTANCE = 1.2;
39 /** @const */ this.MENU_MODE_SCREEN_HEIGHT = 0.5; 39 /** @const */ this.MENU_MODE_SCREEN_HEIGHT = 0.5;
40 /** @const */ this.MENU_MODE_SCREEN_ELEVATION = 0.1; 40 /** @const */ this.MENU_MODE_SCREEN_ELEVATION = 0.1;
41 41
42 this.menuMode = false; 42 this.menuMode = false;
43 this.fullscreen = false; 43 this.fullscreen = false;
44 44
45 let element = new api.UiElement(0, 0, 0, 0); 45 this.uiElement = new DomUiElement('#content-quad-element');
cjgrant 2017/02/15 16:34:28 This is where we tie the content quad to its dummy
46 element.setFill(new api.Content()); 46 this.elementId = this.uiElement.uiElementId;
47 element.setVisible(false); 47
48 element.setSize( 48 let update = new api.UiElementUpdate();
49 this.SCREEN_HEIGHT * this.SCREEN_RATIO, this.SCREEN_HEIGHT); 49 update.setFill(new api.Content());
50 element.setTranslation(0, 0, -this.BROWSING_SCREEN_DISTANCE); 50 update.setVisible(false);
51 this.elementId = ui.addElement(element); 51 ui.updateElement(this.elementId, update);
52 } 52 }
53 53
54 setEnabled(enabled) { 54 setEnabled(enabled) {
55 let update = new api.UiElementUpdate(); 55 let update = new api.UiElementUpdate();
56 update.setVisible(enabled); 56 update.setVisible(enabled);
57 ui.updateElement(this.elementId, update); 57 ui.updateElement(this.elementId, update);
58 if (enabled) { 58 if (enabled) {
59 api.setContentCssSize( 59 api.setContentCssSize(
60 this.CSS_WIDTH_PIXELS, this.CSS_HEIGHT_PIXELS, this.DPR); 60 this.CSS_WIDTH_PIXELS, this.CSS_HEIGHT_PIXELS, this.DPR);
61 } else { 61 } else {
(...skipping 10 matching lines...) Expand all
72 } 72 }
73 73
74 setFullscreen(enabled) { 74 setFullscreen(enabled) {
75 if (this.fullscreen == enabled) 75 if (this.fullscreen == enabled)
76 return; 76 return;
77 this.fullscreen = enabled; 77 this.fullscreen = enabled;
78 this.updateState() 78 this.updateState()
79 } 79 }
80 80
81 updateState() { 81 updateState() {
82 // Defaults content quad parameters.
83 let y = 0;
84 let z = -this.BROWSING_SCREEN_DISTANCE;
85 let height = this.SCREEN_HEIGHT;
86 82
87 // Mode-specific overrides. 83 // Set style according to mode.
cjgrant 2017/02/15 16:34:28 Here, we're taking the app button presses, and pus
84 this.uiElement.domElement.classList.remove('menu');
85 this.uiElement.domElement.classList.remove('fullscreen');
88 if (this.menuMode) { 86 if (this.menuMode) {
89 y = this.MENU_MODE_SCREEN_ELEVATION; 87 this.uiElement.domElement.classList.add('menu');
90 z = -this.MENU_MODE_SCREEN_DISTANCE;
91 height = this.MENU_MODE_SCREEN_HEIGHT;
92 } else if (this.fullscreen) { 88 } else if (this.fullscreen) {
93 z = -this.FULLSCREEN_DISTANCE; 89 this.uiElement.domElement.classList.add('fullscreen');
94 } 90 }
95 91
96 let anim; 92 // let anim;
97 anim = new api.Animation(this.elementId, ANIM_DURATION); 93 // anim = new api.Animation(this.elementId, ANIM_DURATION);
98 anim.setTranslation(0, y, z); 94 // anim.setTranslation(0, y, z);
99 ui.addAnimation(anim); 95 // ui.addAnimation(anim);
100 anim = new api.Animation(this.elementId, ANIM_DURATION); 96 // anim = new api.Animation(this.elementId, ANIM_DURATION);
101 anim.setSize(height * this.SCREEN_RATIO, height); 97 // anim.setSize(height * this.SCREEN_RATIO, height);
102 ui.addAnimation(anim); 98 // ui.addAnimation(anim);
103 } 99 }
104 100
105 // TODO(crbug/643815): Add a method setting aspect ratio (and possible 101 // TODO(crbug/643815): Add a method setting aspect ratio (and possible
106 // animation of changing it). 102 // animation of changing it).
107 103
108 getElementId() { 104 getElementId() {
109 return this.elementId; 105 return this.elementId;
110 } 106 }
111 }; 107 };
112 108
113 class DomUiElement { 109 class DomUiElement {
114 constructor(domId) { 110 constructor(domId) {
115 let domElement = document.querySelector(domId); 111 let domElement = document.querySelector(domId);
116 112
113 // Attach a mutation observer to catch our custom scene style changes.
cjgrant 2017/02/15 16:34:28 Every UI element will have an observer.
114 this.observer = new MutationObserver(function(mutations) {
115 let update = new api.UiElementUpdate();
116 let modifications = false;
117
118 mutations.forEach(function(update, mutation) {
119 modifications = modifications || this.parseCustomStyle(mutation.target , update);
120 }.bind(this, update));
121
122 if (modifications) {
123 ui.updateElement(this.uiElementId, update);
124 }
125 }.bind(this));
126 var config = {
127 attributes: true,
128 subtree: true,
tiborg 2017/02/15 18:36:11 As discussed offline, listening to the sub tree is
129 //attributeFilter: ['style'] // TODO: Better filtering?
cjgrant 2017/02/15 16:34:27 The mutation observer tells us about a lot of stuf
130 };
131 this.observer.observe(domElement, config);
132
117 // Pull copy rectangle from the position of the element. 133 // Pull copy rectangle from the position of the element.
118 let rect = domElement.getBoundingClientRect(); 134 let rect = domElement.getBoundingClientRect();
119 let pixelX = Math.floor(rect.left); 135 let pixelX = Math.floor(rect.left);
120 let pixelY = Math.floor(rect.top); 136 let pixelY = Math.floor(rect.top);
121 let pixelWidth = Math.ceil(rect.right) - pixelX; 137 let pixelWidth = Math.ceil(rect.right) - pixelX;
122 let pixelHeight = Math.ceil(rect.bottom) - pixelY; 138 let pixelHeight = Math.ceil(rect.bottom) - pixelY;
123 139
124 let element = new api.UiElement(pixelX, pixelY, pixelWidth, pixelHeight); 140 let element = new api.UiElement(pixelX, pixelY, pixelWidth, pixelHeight);
125 element.setSize(pixelWidth / 1000, pixelHeight / 1000); 141 element.setSize(pixelWidth / 1000, pixelHeight / 1000);
126 142
127 // Pull additional custom properties from CSS. 143 // Grab initial custom scene styling.
cjgrant 2017/02/15 16:34:28 Here's the initial extraction of element propertie
128 let style = window.getComputedStyle(domElement); 144 this.parseCustomStyle(domElement, element);
129 this.translationX = getStyleFloat(style, '--tranX'); 145 var items = domElement.getElementsByTagName("*");
130 this.translationY = getStyleFloat(style, '--tranY'); 146 for (var i = 0; i < items.length; i++) {
131 this.translationZ = getStyleFloat(style, '--tranZ'); 147 this.parseCustomStyle(items[i], element);
132 element.setTranslation( 148 }
133 this.translationX, this.translationY, this.translationZ);
134 149
135 this.uiElementId = ui.addElement(element); 150 this.uiElementId = ui.addElement(element);
136 this.uiAnimationId = -1; 151 this.uiAnimationId = -1;
137 this.domElement = domElement; 152 this.domElement = domElement;
138 } 153 }
154
155 parseCustomStyle(element, update) {
156 let propertyMap = {
157 '--tranX': 'translationX',
cjgrant 2017/02/15 16:34:28 This list is all custom properties that can enact
158 '--tranY': 'translationY',
159 '--tranZ': 'translationZ',
160 '--sizeX': 'sizeX',
161 '--sizeY': 'sizeY',
162 '--scaleX': 'scaleX',
163 '--scaleY': 'scaleY',
164 '--scaleZ': 'scaleZ',
165 '--rotationX': 'rotationX',
166 '--rotationY': 'rotationY',
167 '--rotationZ': 'rotationZ',
168 '--rotationAngle': 'rotationAngle',
169 '--opacity': 'opacity',
170 };
171
172 // For each custom property we recognize, apply its value to the
173 // corresponding UI element property.
174 let cs = window.getComputedStyle(element);
175 let keys = Object.keys(propertyMap);
176 let len = keys.length;
177 let modifications = false;
178 for (var i = 0; i < len; i++) {
179 let item = keys[i];
180
181 let value = parseFloat(cs.getPropertyValue(item));
182 if (isNaN(value))
183 continue;
184 update.properties[propertyMap[item]] = value;
185 modifications = true;
186 }
187 return modifications;
188 }
139 }; 189 };
140 190
141 class RoundButton extends DomUiElement { 191 class RoundButton extends DomUiElement {
142 constructor(domId, callback) { 192 constructor(domId, callback) {
143 super(domId); 193 super(domId);
144 194
145 let button = this.domElement.querySelector('.button'); 195 let button = this.domElement.querySelector('.button');
146 button.addEventListener('mouseenter', this.onMouseEnter.bind(this)); 196 button.addEventListener('mouseenter', this.onMouseEnter.bind(this));
147 button.addEventListener('mouseleave', this.onMouseLeave.bind(this)); 197 button.addEventListener('mouseleave', this.onMouseLeave.bind(this));
148 button.addEventListener('click', callback); 198 button.addEventListener('click', callback);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 api.doAction(api.Action.RELOAD, {}); 239 api.doAction(api.Action.RELOAD, {});
190 } 240 }
191 ], 241 ],
192 [ 242 [
193 '#forward', 243 '#forward',
194 function() { 244 function() {
195 api.doAction(api.Action.HISTORY_FORWARD, {}); 245 api.doAction(api.Action.HISTORY_FORWARD, {});
196 } 246 }
197 ], 247 ],
198 ]; 248 ];
199 249
cjgrant 2017/02/15 16:34:28 This kind of stuff is hard to put in CSS. It desc
200 /** @const */ var BUTTON_Y = -0.27; 250 /** @const */ var BUTTON_Y = -0.27;
201 /** @const */ var BUTTON_Z = -1; 251 /** @const */ var BUTTON_Z = -1;
202 /** @const */ var BUTTON_SPACING = 0.11; 252 /** @const */ var BUTTON_SPACING = 0.11;
203 253
204 let startPosition = -BUTTON_SPACING * (descriptors.length / 2.0 - 0.5); 254 let startPosition = -BUTTON_SPACING * (descriptors.length / 2.0 - 0.5);
205 for (let i = 0; i < descriptors.length; i++) { 255 for (let i = 0; i < descriptors.length; i++) {
206 // Use an invisible parent to simplify Z-axis movement on hover. 256 // Use an invisible parent to simplify Z-axis movement on hover.
207 let position = new api.UiElement(0, 0, 0, 0); 257 let position = new api.UiElement(0, 0, 0, 0);
208 position.setVisible(false); 258 position.setVisible(false);
209 position.setTranslation( 259 position.setTranslation(
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 !this.loading && this.visibilityTimeout > 0 && !this.visibilityTimer; 534 !this.loading && this.visibilityTimeout > 0 && !this.visibilityTimer;
485 if (shouldBeHidden != this.hidden) { 535 if (shouldBeHidden != this.hidden) {
486 // Make the box fade away if it's disappearing. 536 // Make the box fade away if it's disappearing.
487 this.hidden = shouldBeHidden; 537 this.hidden = shouldBeHidden;
488 538
489 // Fade-out or fade-in the box. 539 // Fade-out or fade-in the box.
490 let opacityAnimation = 540 let opacityAnimation =
491 new api.Animation(this.domUiElement.uiElementId, this.fadeTimeMs); 541 new api.Animation(this.domUiElement.uiElementId, this.fadeTimeMs);
492 opacityAnimation.setOpacity(this.hidden ? 0.0 : this.opacity); 542 opacityAnimation.setOpacity(this.hidden ? 0.0 : this.opacity);
493 ui.addAnimation(opacityAnimation); 543 ui.addAnimation(opacityAnimation);
494
495 // Drop the position as it fades, or raise the position if appearing.
496 let yOffset = this.hidden ? this.fadeYOffset : 0;
497 let positionAnimation =
498 new api.Animation(this.domUiElement.uiElementId, this.fadeTimeMs);
499 positionAnimation.setTranslation(
500 this.domUiElement.translationX,
501 this.domUiElement.translationY + yOffset,
502 this.domUiElement.translationZ);
503 ui.addAnimation(positionAnimation);
504 } 544 }
505 545
506 ui.flush(); 546 ui.flush();
507 } 547 }
508 548
509 setNativeVisibility(visible) { 549 setNativeVisibility(visible) {
510 if (visible == this.nativeState.visible) { 550 if (visible == this.nativeState.visible) {
511 return; 551 return;
512 } 552 }
513 this.nativeState.visible = visible; 553 this.nativeState.visible = visible;
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 setEnabled(enabled) { 819 setEnabled(enabled) {
780 let visibilityUpdate = new api.UiElementUpdate(); 820 let visibilityUpdate = new api.UiElementUpdate();
781 visibilityUpdate.setVisible(enabled); 821 visibilityUpdate.setVisible(enabled);
782 ui.updateElement(this.tabContainerElement.uiElementId, visibilityUpdate); 822 ui.updateElement(this.tabContainerElement.uiElementId, visibilityUpdate);
783 } 823 }
784 }; 824 };
785 825
786 class UiManager { 826 class UiManager {
787 constructor() { 827 constructor() {
788 this.mode = api.Mode.UNKNOWN; 828 this.mode = api.Mode.UNKNOWN;
789 this.menuMode = false; 829 // this.menuMode = false;
830 this.menuMode = true;
790 this.fullscreen = false; 831 this.fullscreen = false;
791 832
792 this.background = new Background(); 833 this.background = new Background();
793 this.contentQuad = new ContentQuad(); 834 this.contentQuad = new ContentQuad();
794 let contentId = this.contentQuad.getElementId(); 835 let contentId = this.contentQuad.getElementId();
795 836
796 this.controls = new Controls(contentId); 837 this.controls = new Controls(contentId);
797 this.secureOriginWarnings = new SecureOriginWarnings(); 838 this.secureOriginWarnings = new SecureOriginWarnings();
798 this.urlIndicator = new UrlIndicator(); 839 this.urlIndicator = new UrlIndicator();
799 this.omnibox = new Omnibox(); 840 this.omnibox = new Omnibox();
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 nativeCommandHandler.handleCommand(dict); 990 nativeCommandHandler.handleCommand(dict);
950 } 991 }
951 992
952 return { 993 return {
953 initialize: initialize, 994 initialize: initialize,
954 command: command, 995 command: command,
955 }; 996 };
956 })(); 997 })();
957 998
958 window.addEventListener('load', vrShellUi.initialize); 999 window.addEventListener('load', vrShellUi.initialize);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698