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

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

Issue 2698033002: PROTOTYPE: Generic custom CSS property parsing (Closed)
Patch Set: Rebase to ToT (native support is now in tip). 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
« no previous file with comments | « chrome/browser/resources/vr_shell/vr_shell_ui.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 25 matching lines...) Expand all
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 /** @const */ this.BACKGROUND_DISTANCE_MULTIPLIER = 1.414; 41 /** @const */ this.BACKGROUND_DISTANCE_MULTIPLIER = 1.414;
42 42
43 this.menuMode = false; 43 this.menuMode = false;
44 this.fullscreen = false; 44 this.fullscreen = false;
45 45
46 let element = new api.UiElement(0, 0, 0, 0); 46 this.uiElement = new DomUiElement('#content-quad-element');
47 element.setFill(new api.Content()); 47 this.elementId = this.uiElement.uiElementId;
48 element.setVisible(false); 48
49 element.setSize( 49 let update = new api.UiElementUpdate();
50 this.SCREEN_HEIGHT * this.SCREEN_RATIO, this.SCREEN_HEIGHT); 50 update.setFill(new api.Content());
51 element.setTranslation(0, 0, -this.BROWSING_SCREEN_DISTANCE); 51 update.setVisible(false);
52 this.elementId = ui.addElement(element); 52 ui.updateElement(this.elementId, update);
53 53
54 // Place an invisible but hittable plane behind the content quad, to keep 54 // Place an invisible but hittable plane behind the content quad, to keep
55 // the reticle roughly planar with the content if near content. 55 // the reticle roughly planar with the content if near content.
56 let backPlane = new api.UiElement(0, 0, 0, 0); 56 let backPlane = new api.UiElement(0, 0, 0, 0);
57 backPlane.setVisible(false); 57 backPlane.setVisible(false);
58 backPlane.setHitTestable(true); 58 backPlane.setHitTestable(true);
59 backPlane.setSize(1000, 1000); 59 backPlane.setSize(1000, 1000);
60 backPlane.setTranslation(0, 0, -0.01); 60 backPlane.setTranslation(0, 0, -0.01);
61 backPlane.setParentId(this.elementId); 61 backPlane.setParentId(this.elementId);
62 ui.addElement(backPlane); 62 ui.addElement(backPlane);
(...skipping 22 matching lines...) Expand all
85 } 85 }
86 86
87 setFullscreen(enabled) { 87 setFullscreen(enabled) {
88 if (this.fullscreen == enabled) 88 if (this.fullscreen == enabled)
89 return; 89 return;
90 this.fullscreen = enabled; 90 this.fullscreen = enabled;
91 this.updateState() 91 this.updateState()
92 } 92 }
93 93
94 updateState() { 94 updateState() {
95 // Defaults content quad parameters. 95 // Set style according to mode.
96 let y = 0; 96 this.uiElement.domElement.classList.remove('menu');
97 let distance = this.BROWSING_SCREEN_DISTANCE; 97 this.uiElement.domElement.classList.remove('fullscreen');
98 let height = this.SCREEN_HEIGHT;
99
100 // Mode-specific overrides.
101 if (this.menuMode) { 98 if (this.menuMode) {
102 y = this.MENU_MODE_SCREEN_ELEVATION; 99 this.uiElement.domElement.classList.add('menu');
103 distance = this.MENU_MODE_SCREEN_DISTANCE;
104 height = this.MENU_MODE_SCREEN_HEIGHT;
105 } else if (this.fullscreen) { 100 } else if (this.fullscreen) {
106 distance = this.FULLSCREEN_DISTANCE; 101 this.uiElement.domElement.classList.add('fullscreen');
107 } 102 }
108 103
109 let anim; 104 //ui.setBackgroundDistance(distance * this.BACKGROUND_DISTANCE_MULTIPLIER) ;
110 anim = new api.Animation(this.elementId, ANIM_DURATION);
111 anim.setTranslation(0, y, -distance);
112 ui.addAnimation(anim);
113 anim = new api.Animation(this.elementId, ANIM_DURATION);
114 anim.setSize(height * this.SCREEN_RATIO, height);
115 ui.addAnimation(anim);
116
117 ui.setBackgroundDistance(distance * this.BACKGROUND_DISTANCE_MULTIPLIER);
118 } 105 }
119 106
120 // TODO(crbug/643815): Add a method setting aspect ratio (and possible 107 // TODO(crbug/643815): Add a method setting aspect ratio (and possible
121 // animation of changing it). 108 // animation of changing it).
122 109
123 getElementId() { 110 getElementId() {
124 return this.elementId; 111 return this.elementId;
125 } 112 }
126 }; 113 };
127 114
128 class DomUiElement { 115 class DomUiElement {
129 constructor(domId) { 116 constructor(domId) {
130 let domElement = document.querySelector(domId); 117 let domElement = document.querySelector(domId);
131 118
119 // Attach a mutation observer to catch our custom scene style changes.
120 this.observer = new MutationObserver(function(mutations) {
121 let update = new api.UiElementUpdate();
122 let modifications = false;
123
124 mutations.forEach(function(update, mutation) {
125 modifications = modifications || this.parseCustomStyle(mutation.target , update);
126 }.bind(this, update));
127
128 if (modifications) {
129 ui.updateElement(this.uiElementId, update);
130 }
131 }.bind(this));
132 var config = {
133 attributes: true,
134 subtree: true,
135 //attributeFilter: ['style'] // TODO: Better filtering?
136 };
137 this.observer.observe(domElement, config);
138
132 // Pull copy rectangle from the position of the element. 139 // Pull copy rectangle from the position of the element.
133 let rect = domElement.getBoundingClientRect(); 140 let rect = domElement.getBoundingClientRect();
134 let pixelX = Math.floor(rect.left); 141 let pixelX = Math.floor(rect.left);
135 let pixelY = Math.floor(rect.top); 142 let pixelY = Math.floor(rect.top);
136 let pixelWidth = Math.ceil(rect.right) - pixelX; 143 let pixelWidth = Math.ceil(rect.right) - pixelX;
137 let pixelHeight = Math.ceil(rect.bottom) - pixelY; 144 let pixelHeight = Math.ceil(rect.bottom) - pixelY;
138 145
139 let element = new api.UiElement(pixelX, pixelY, pixelWidth, pixelHeight); 146 let element = new api.UiElement(pixelX, pixelY, pixelWidth, pixelHeight);
140 element.setSize(pixelWidth / 1000, pixelHeight / 1000); 147 element.setSize(pixelWidth / 1000, pixelHeight / 1000);
141 148
142 // Pull additional custom properties from CSS. 149 // Grab initial custom scene styling.
143 let style = window.getComputedStyle(domElement); 150 this.parseCustomStyle(domElement, element);
144 this.translationX = getStyleFloat(style, '--tranX'); 151 var items = domElement.getElementsByTagName("*");
145 this.translationY = getStyleFloat(style, '--tranY'); 152 for (var i = 0; i < items.length; i++) {
146 this.translationZ = getStyleFloat(style, '--tranZ'); 153 this.parseCustomStyle(items[i], element);
147 element.setTranslation( 154 }
148 this.translationX, this.translationY, this.translationZ);
149 155
150 this.uiElementId = ui.addElement(element); 156 this.uiElementId = ui.addElement(element);
151 this.uiAnimationId = -1; 157 this.uiAnimationId = -1;
152 this.domElement = domElement; 158 this.domElement = domElement;
153 } 159 }
160
161 parseCustomStyle(element, update) {
162 let propertyMap = {
163 '--tranX': 'translationX',
164 '--tranY': 'translationY',
165 '--tranZ': 'translationZ',
166 '--sizeX': 'sizeX',
167 '--sizeY': 'sizeY',
168 '--scaleX': 'scaleX',
169 '--scaleY': 'scaleY',
170 '--scaleZ': 'scaleZ',
171 '--rotationX': 'rotationX',
172 '--rotationY': 'rotationY',
173 '--rotationZ': 'rotationZ',
174 '--rotationAngle': 'rotationAngle',
175 '--opacity': 'opacity',
176 };
177
178 // For each custom property we recognize, apply its value to the
179 // corresponding UI element property.
180 let cs = window.getComputedStyle(element);
181 let keys = Object.keys(propertyMap);
182 let len = keys.length;
183 let modifications = false;
184 for (var i = 0; i < len; i++) {
185 let item = keys[i];
186
187 let value = parseFloat(cs.getPropertyValue(item));
188 if (isNaN(value))
189 continue;
190 update.properties[propertyMap[item]] = value;
191 modifications = true;
192 }
193 return modifications;
194 }
154 }; 195 };
155 196
156 class RoundButton extends DomUiElement { 197 class RoundButton extends DomUiElement {
157 constructor(domId, callback) { 198 constructor(domId, callback) {
158 super(domId); 199 super(domId);
159 200
160 let button = this.domElement.querySelector('.button'); 201 let button = this.domElement.querySelector('.button');
161 button.addEventListener('mouseenter', this.onMouseEnter.bind(this)); 202 button.addEventListener('mouseenter', this.onMouseEnter.bind(this));
162 button.addEventListener('mouseleave', this.onMouseLeave.bind(this)); 203 button.addEventListener('mouseleave', this.onMouseLeave.bind(this));
163 button.addEventListener('click', callback); 204 button.addEventListener('click', callback);
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 !this.loading && this.visibilityTimeout > 0 && !this.visibilityTimer; 540 !this.loading && this.visibilityTimeout > 0 && !this.visibilityTimer;
500 if (shouldBeHidden != this.hidden) { 541 if (shouldBeHidden != this.hidden) {
501 // Make the box fade away if it's disappearing. 542 // Make the box fade away if it's disappearing.
502 this.hidden = shouldBeHidden; 543 this.hidden = shouldBeHidden;
503 544
504 // Fade-out or fade-in the box. 545 // Fade-out or fade-in the box.
505 let opacityAnimation = 546 let opacityAnimation =
506 new api.Animation(this.domUiElement.uiElementId, this.fadeTimeMs); 547 new api.Animation(this.domUiElement.uiElementId, this.fadeTimeMs);
507 opacityAnimation.setOpacity(this.hidden ? 0.0 : this.opacity); 548 opacityAnimation.setOpacity(this.hidden ? 0.0 : this.opacity);
508 ui.addAnimation(opacityAnimation); 549 ui.addAnimation(opacityAnimation);
509
510 // Drop the position as it fades, or raise the position if appearing.
511 let yOffset = this.hidden ? this.fadeYOffset : 0;
512 let positionAnimation =
513 new api.Animation(this.domUiElement.uiElementId, this.fadeTimeMs);
514 positionAnimation.setTranslation(
515 this.domUiElement.translationX,
516 this.domUiElement.translationY + yOffset,
517 this.domUiElement.translationZ);
518 ui.addAnimation(positionAnimation);
519 } 550 }
520 551
521 ui.flush(); 552 ui.flush();
522 } 553 }
523 554
524 setNativeVisibility(visible) { 555 setNativeVisibility(visible) {
525 if (visible == this.nativeState.visible) { 556 if (visible == this.nativeState.visible) {
526 return; 557 return;
527 } 558 }
528 this.nativeState.visible = visible; 559 this.nativeState.visible = visible;
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 setEnabled(enabled) { 827 setEnabled(enabled) {
797 let visibilityUpdate = new api.UiElementUpdate(); 828 let visibilityUpdate = new api.UiElementUpdate();
798 visibilityUpdate.setVisible(enabled); 829 visibilityUpdate.setVisible(enabled);
799 ui.updateElement(this.tabContainerElement.uiElementId, visibilityUpdate); 830 ui.updateElement(this.tabContainerElement.uiElementId, visibilityUpdate);
800 } 831 }
801 }; 832 };
802 833
803 class UiManager { 834 class UiManager {
804 constructor() { 835 constructor() {
805 this.mode = api.Mode.UNKNOWN; 836 this.mode = api.Mode.UNKNOWN;
806 this.menuMode = false; 837 // this.menuMode = false;
838 this.menuMode = true;
807 this.fullscreen = false; 839 this.fullscreen = false;
808 840
809 this.background = new Background(); 841 this.background = new Background();
810 this.contentQuad = new ContentQuad(); 842 this.contentQuad = new ContentQuad();
811 let contentId = this.contentQuad.getElementId(); 843 let contentId = this.contentQuad.getElementId();
812 844
813 this.controls = new Controls(contentId); 845 this.controls = new Controls(contentId);
814 this.secureOriginWarnings = new SecureOriginWarnings(); 846 this.secureOriginWarnings = new SecureOriginWarnings();
815 this.urlIndicator = new UrlIndicator(); 847 this.urlIndicator = new UrlIndicator();
816 this.omnibox = new Omnibox(); 848 this.omnibox = new Omnibox();
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 nativeCommandHandler.handleCommand(dict); 998 nativeCommandHandler.handleCommand(dict);
967 } 999 }
968 1000
969 return { 1001 return {
970 initialize: initialize, 1002 initialize: initialize,
971 command: command, 1003 command: command,
972 }; 1004 };
973 })(); 1005 })();
974 1006
975 window.addEventListener('load', vrShellUi.initialize); 1007 window.addEventListener('load', vrShellUi.initialize);
OLDNEW
« no previous file with comments | « chrome/browser/resources/vr_shell/vr_shell_ui.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698