Переглянути джерело

Merge pull request #3037 from RaananW/viewer-changes

Viewer changes
Raanan Weber 7 роки тому
батько
коміт
3107e188b5

+ 3 - 3
Viewer/assets/templates/default/defaultTemplate.html

@@ -7,9 +7,9 @@
         display: flex;
         justify-content: center;
         align-items: center;
-        -webkit-transition: opacity 1.5s ease;
-        -moz-transition: opacity 1.5s ease;
-        transition: opacity 1.5s ease;
+        -webkit-transition: opacity 2s ease;
+        -moz-transition: opacity 2s ease;
+        transition: opacity 2s ease;
     }
 
     viewer {

+ 3 - 3
Viewer/assets/templates/default/defaultViewer.html

@@ -14,9 +14,8 @@
         background-color: rgba(0, 0, 0, 0.3);
         color: white;
         transition: 1s;
-
-        align-items: center;
-        justify-content: center;
+        align-items: flex-start;
+        justify-content: space-around;
         display: flex;
 
         flex-direction: column;
@@ -26,6 +25,7 @@
 
     @media screen and (min-width: 768px) {
         nav-bar {
+            align-items: center;
             flex-direction: row;
             justify-content: space-between;
             height: 80px;

+ 3 - 2
Viewer/assets/templates/default/navbar.html

@@ -1,6 +1,7 @@
 <style>
     div.flex-container {
         display: flex;
+        width: 100%;
     }
 
     div.thumbnail {
@@ -31,7 +32,7 @@
 
     div.button-container {
         align-items: center;
-        display: flex;
+        justify-content: flex-end;
     }
 
     div.button {
@@ -57,7 +58,7 @@
         <span class="model-subtitle"> {{#if subtitle}}{{subtitle}} {{/if}}</span>
     </div>
 </div>
-<div class="button-container">
+<div class="button-container flex-container">
     <!-- holding the buttons -->
     {{#each buttons}}
     <div id="{{id}}" class="button">

+ 4 - 2
Viewer/dist/basicExample.html

@@ -8,8 +8,10 @@
         <title>BabylonJS Viewer - Basic usage</title>
         <style>
             babylon {
-                width: 800px;
-                height: 500px;
+                max-width: 800px;
+                max-height: 500px;
+                width: 100%;
+                height: 100%;
             }
         </style>
     </head>

Різницю між файлами не показано, бо вона завелика
+ 64 - 24
Viewer/dist/viewer.js


+ 11 - 6
Viewer/src/templateManager.ts

@@ -24,7 +24,7 @@ export interface TemplateConfiguration {
         dragstart?: boolean | Array<string>;
         drop?: boolean | Array<string>;
 
-        [key: string]: boolean | Array<string>;
+        [key: string]: boolean | Array<string> | undefined;
     }
     children?: { [name: string]: TemplateConfiguration };
 }
@@ -61,7 +61,7 @@ export class TemplateManager {
 
         let childrenMap = configuration.children || {};
         let childrenTemplates = Object.keys(childrenMap).map(name => {
-            return this.initTemplate(configuration.children[name], name, template);
+            return this.initTemplate(childrenMap[name], name, template);
         });
 
         // register the observers
@@ -85,7 +85,7 @@ export class TemplateManager {
     }
 
     // assumiung only ONE(!) canvas
-    public getCanvas(): HTMLCanvasElement {
+    public getCanvas(): HTMLCanvasElement | null {
         return this.containerElement.querySelector('canvas');
     }
 
@@ -201,7 +201,7 @@ export class Template {
     private registerEvents() {
         if (this.configuration.events) {
             Object.keys(this.configuration.events).forEach(eventName => {
-                if (this.configuration.events[eventName]) {
+                if (this.configuration.events && this.configuration.events[eventName]) {
                     let functionToFire = (selector, event) => {
                         this.onEventTriggered.notifyObservers({ event: event, template: this, selector: selector });
                     }
@@ -225,7 +225,7 @@ export class Template {
 
 export function getTemplateAsHtml(templateConfig: TemplateConfiguration): Promise<string> {
     if (!templateConfig) {
-        return Promise.resolve(undefined);
+        return Promise.reject('No templateConfig provided');
     } else if (templateConfig.html) {
         return Promise.resolve(templateConfig.html);
     } else {
@@ -234,7 +234,12 @@ export function getTemplateAsHtml(templateConfig: TemplateConfiguration): Promis
             return loadFile(location);
         } else {
             location = location.replace('#', '');
-            document.getElementById('#' + location);
+            let element = document.getElementById('#' + location);
+            if (element) {
+                return Promise.resolve(element.innerHTML);
+            } else {
+                return Promise.reject('Template ID not found');
+            }
         }
     }
 }

+ 54 - 17
Viewer/src/viewer/defaultViewer.ts

@@ -25,19 +25,37 @@ export class DefaultViewer extends AbstractViewer {
         // navbar
         let viewerElement = this.templateManager.getTemplate('viewer');
         let navbar = this.templateManager.getTemplate('navBar');
+        let navbarHeight = navbar.parent.clientHeight + 'px';
 
-        let nextHeight: string = '0px';
+        let navbarShown: boolean = true;
 
-        viewerElement.parent.addEventListener('pointerover', () => {
-            let currentHeight = navbar.parent.clientHeight + 'px';
-            navbar.parent.style.bottom = nextHeight;
-            nextHeight = '-' + currentHeight;
-            console.log(nextHeight, currentHeight);
+        viewerElement.parent.addEventListener('pointerout', () => {
+            if (navbarShown) return;
+            navbar.parent.style.bottom = '0px';
+            navbarShown = true;
         });
 
-        viewerElement.parent.addEventListener('pointerout', () => {
-            navbar.parent.style.bottom = nextHeight;
-            nextHeight = '0px';
+        let timeoutCancel;
+
+        viewerElement.parent.addEventListener('pointerdown', () => {
+            if (!navbarShown) return;
+            navbar.parent.style.bottom = '-' + navbarHeight;
+            navbarShown = false;
+
+            if (timeoutCancel) {
+                clearTimeout(timeoutCancel);
+            }
+        });
+
+        viewerElement.parent.addEventListener('pointerup', () => {
+            if (timeoutCancel) {
+                clearTimeout(timeoutCancel);
+            }
+
+            timeoutCancel = setTimeout(() => {
+                navbar.parent.style.bottom = '0px';
+                navbarShown = true;
+            }, 2000)
         });
 
         // events registration
@@ -93,7 +111,11 @@ export class DefaultViewer extends AbstractViewer {
         // here we could set the navbar's model information:
         this.setModelMetaData();
 
-        this.hideLoadingScreen();
+        // with a short timeout, making sure everything is there already.
+        setTimeout(() => {
+            this.hideLoadingScreen();
+        }, 500);
+
 
         // recreate the camera
         this.scene.createDefaultCameraOrLight(true, true, true);
@@ -113,13 +135,19 @@ export class DefaultViewer extends AbstractViewer {
         let metadataContainer = navbar.parent.querySelector('#model-metadata');
 
         //title
-        if (typeof this.configuration.model === 'object') {
+        if (metadataContainer && typeof this.configuration.model === 'object') {
             if (this.configuration.model.title) {
-                metadataContainer.querySelector('span.model-title').innerHTML = this.configuration.model.title;
+                let element = metadataContainer.querySelector('span.model-title');
+                if (element) {
+                    element.innerHTML = this.configuration.model.title;
+                }
             }
 
             if (this.configuration.model.subtitle) {
-                metadataContainer.querySelector('span.model-subtitle').innerHTML = this.configuration.model.subtitle;
+                let element = metadataContainer.querySelector('span.model-subtitle');
+                if (element) {
+                    element.innerHTML = this.configuration.model.subtitle;
+                }
             }
 
             if (this.configuration.model.thumbnail) {
@@ -208,7 +236,10 @@ export class DefaultViewer extends AbstractViewer {
     }
 
     private setupLights(focusMeshes: Array<AbstractMesh> = []) {
-        if (!this.configuration.scene.defaultLight && (this.configuration.lights && this.configuration.lights.length)) {
+
+        let sceneConfig = this.configuration.scene || { defaultLight: true };
+
+        if (!sceneConfig.defaultLight && (this.configuration.lights && this.configuration.lights.length)) {
             // remove old lights
             this.scene.lights.forEach(l => {
                 l.dispose();
@@ -242,7 +273,10 @@ export class DefaultViewer extends AbstractViewer {
     }
 
     private setupCamera(focusMeshes: Array<AbstractMesh> = []) {
-        if (this.configuration.scene.defaultCamera) {
+
+        let sceneConfig = this.configuration.scene || { autoRotate: false, defaultCamera: true };
+
+        if (sceneConfig.defaultCamera) {
             return;
         }
 
@@ -265,7 +299,7 @@ export class DefaultViewer extends AbstractViewer {
             });
         };
 
-        if (this.configuration.scene.autoRotate) {
+        if (sceneConfig.autoRotate) {
             this.camera.useAutoRotationBehavior = true;
         }
     }
@@ -275,7 +309,7 @@ export class DefaultViewer extends AbstractViewer {
         [propName: string]: any;
     }, payload: any) {
 
-        let behavior: Behavior<ArcRotateCamera>;
+        let behavior: Behavior<ArcRotateCamera> | null;
         let type = (typeof behaviorConfig !== "object") ? behaviorConfig : behaviorConfig.type;
 
         let config: { [propName: string]: any } = (typeof behaviorConfig === "object") ? behaviorConfig : {};
@@ -291,6 +325,9 @@ export class DefaultViewer extends AbstractViewer {
             case CameraBehavior.FRAMING:
                 behavior = new FramingBehavior();
                 break;
+            default:
+                behavior = null;
+                break;
         }
 
         if (behavior) {

+ 5 - 1
Viewer/src/viewer/viewer.ts

@@ -29,7 +29,8 @@ export abstract class AbstractViewer {
         configurationLoader.loadConfiguration(initialConfiguration).then((configuration) => {
             this.configuration = configuration;
             // initialize the templates
-            this.templateManager.initTemplate(this.configuration.template);
+            let templateConfiguration = this.configuration.template || {};
+            this.templateManager.initTemplate(templateConfiguration);
             // when done, execute onTemplatesLoaded()
             this.templateManager.onAllLoaded.add(() => {
                 this.onTemplatesLoaded();
@@ -69,6 +70,9 @@ export abstract class AbstractViewer {
      */
     protected initEngine(): Promise<Engine> {
         let canvasElement = this.templateManager.getCanvas();
+        if (!canvasElement) {
+            return Promise.reject('Canvas element not found!');
+        }
         let config = this.configuration.engine || {};
         // TDO enable further configuration
         this.engine = new Engine(canvasElement, !!config.antialiasing);

+ 1 - 0
Viewer/tsconfig.json

@@ -4,6 +4,7 @@
         "module": "commonjs",
         "noResolve": true,
         "noImplicitAny": false, //mainly due to usage of external libs without typings.
+        "strictNullChecks": true,
         "removeComments": true,
         "preserveConstEnums": true,
         "sourceMap": true,