Browse Source

Adding fullscreen button and design improvements
fullscreen button is now a part of the default viewer. Title, subtitle and thumbnail are now a part of the model object (or the template, if wanted).

Raanan Weber 7 years ago
parent
commit
8f1304d644

BIN
Viewer/assets/img/fullscreen.png


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

@@ -20,6 +20,9 @@
         z-index: 1;
         z-index: 1;
         justify-content: center;
         justify-content: center;
         align-items: center;
         align-items: center;
+
+        width: 100%;
+        height: 100%;
     }
     }
 </style>
 </style>
 
 

+ 1 - 2
Viewer/assets/templates/default/defaultViewer.html

@@ -11,8 +11,7 @@
         height: 160px;
         height: 160px;
         width: 100%;
         width: 100%;
         bottom: 0;
         bottom: 0;
-        opacity: 0.3;
-        background-color: black;
+        background-color: rgba(0, 0, 0, 0.3);
         color: white;
         color: white;
         transition: 1s;
         transition: 1s;
 
 

+ 24 - 27
Viewer/assets/templates/default/navbar.html

@@ -6,31 +6,29 @@
     div.thumbnail {
     div.thumbnail {
         position: relative;
         position: relative;
         overflow: hidden;
         overflow: hidden;
-        display: flex;
-        width: 90px;
-    }
-
-    div.thumbnail img {
-        position: absolute;
-        left: 50%;
-        top: 50%;
-        height: 100%;
-        width: auto;
-        border-radius: 50%;
-        -webkit-transform: translate(-50%, -50%);
-        -ms-transform: translate(-50%, -50%);
-        transform: translate(-50%, -50%);
+        display: block;
+        width: 40px;
+        height: 40px;
+        background-size: cover;
+        background-position: center;
+        border-radius: 20px;
+        margin: 0 10px;
     }
     }
 
 
     div.title-container {
     div.title-container {
         flex-direction: column;
         flex-direction: column;
         display: flex;
         display: flex;
+        justify-content: space-between;
     }
     }
 
 
     span.model-title {
     span.model-title {
         font-size: 125%;
         font-size: 125%;
     }
     }
 
 
+    span.model-subtitle {
+        font-size: 90%;
+    }
+
     div.button-container {
     div.button-container {
         align-items: center;
         align-items: center;
         display: flex;
         display: flex;
@@ -47,26 +45,25 @@
     }
     }
 </style>
 </style>
 
 
-<div class="flex-container">
+<div class="flex-container" id="model-metadata">
     <!-- holding the description -->
     <!-- holding the description -->
     <div class="thumbnail">
     <div class="thumbnail">
-        <!-- holding the thumbnail -->
-        <img src="{{thumbnail}}" alt="{{title}}">
+        <!-- holding the thumbnail 
+        <img src="{{thumbnail}}" alt="{{title}}">-->
     </div>
     </div>
     <div class="title-container">
     <div class="title-container">
-        <span class="model-title">{{title}}</span>
-        <span class="model-subtitle">{{subtitle}}</span>
+
+        <span class="model-title">{{#if title}}{{title}}{{/if}}</span>
+        <span class="model-subtitle"> {{#if subtitle}}{{subtitle}} {{/if}}</span>
     </div>
     </div>
 </div>
 </div>
 <div class="button-container">
 <div class="button-container">
     <!-- holding the buttons -->
     <!-- holding the buttons -->
-    <div class="button">
-        <img src="{{thumbnail}}" alt="{{title}}">
-    </div>
-    <div class="button">
-        <img src="{{thumbnail}}" alt="{{title}}">
-    </div>
-    <div class="button">
-        <img src="{{thumbnail}}" alt="{{title}}">
+    {{#each buttons}}
+    <div id="{{id}}" class="button">
+        {{#if text}}
+        <span>{{text}}</span>> {{/if}} {{#if image}}
+        <img src="{{image}}" alt="{{altText}}"> {{/if}}
     </div>
     </div>
+    {{/each}}
 </div>
 </div>

+ 2 - 1
Viewer/dist/basicExample.html

@@ -15,7 +15,8 @@
     </head>
     </head>
 
 
     <body>
     <body>
-        <babylon model="https://ugcorigin.s-microsoft.com/12/2e77b8e3-0000-0000-7a48-6505db2f0ef9/952/1508427934473.gltf" default-viewer="true"></babylon>
+        <babylon model.title="The Bus!" model.subtitle="Remix3D" model.thumbnail="http://d33wubrfki0l68.cloudfront.net/7e08139ddee0ec38005f4232346c7f7386831300/fd934/githubuniverse/remix3d.png"
+            model.url="https://ugcorigin.s-microsoft.com/12/2e77b8e3-0000-0000-7a48-6505db2f0ef9/952/1508427934473.gltf" default-viewer="true"></babylon>
         <script src="viewer.js"></script>
         <script src="viewer.js"></script>
     </body>
     </body>
 
 

+ 12 - 3
Viewer/src/configuration/configuration.ts

@@ -33,6 +33,8 @@ export interface ViewerConfiguration {
         rotation?: { x: number, y: number, z: number, w: number };
         rotation?: { x: number, y: number, z: number, w: number };
         scaling?: { x: number, y: number, z: number };
         scaling?: { x: number, y: number, z: number };
         parentObjectIndex?: number; // the index of the parent object of the model in the loaded meshes array.
         parentObjectIndex?: number; // the index of the parent object of the model in the loaded meshes array.
+
+        [propName: string]: any; // further configuration, like title and creator
     } | string,
     } | string,
 
 
     description?: string | {
     description?: string | {
@@ -184,9 +186,16 @@ export let defaultConfiguration: ViewerConfiguration = {
                     navBar: {
                     navBar: {
                         html: require("../../assets/templates/default/navbar.html"),
                         html: require("../../assets/templates/default/navbar.html"),
                         config: {
                         config: {
-                            thumbnail: require('../../assets/img/loading.png'),
-                            title: "Title",
-                            subtitle: "Subtitle"
+                            buttons: [
+                                {
+                                    id: 'fullscreen-button',
+                                    altText: "Fullscreen",
+                                    image: require('../../assets/img/fullscreen.png')
+                                }
+                            ]
+                        },
+                        events: {
+                            pointerdown: ['#fullscreen-button']
                         }
                         }
                     }
                     }
                 }
                 }

+ 60 - 0
Viewer/src/viewer/defaultViewer.ts

@@ -40,9 +40,44 @@ export class DefaultViewer extends AbstractViewer {
             nextHeight = '0px';
             nextHeight = '0px';
         });
         });
 
 
+        // events registration
+        this.registerFullscreenMode();
+
         return super.onTemplatesLoaded();
         return super.onTemplatesLoaded();
     }
     }
 
 
+    private registerFullscreenMode() {
+        let isFullscreen = false;
+
+        let navbar = this.templateManager.getTemplate('navBar');
+        let viewerElement = this.templateManager.getTemplate('viewer').parent;
+
+        navbar.onEventTriggered.add((data) => {
+            switch (data.event.type) {
+                case 'pointerdown':
+                    let event: PointerEvent = <PointerEvent>data.event;
+                    if (event.button === 0) {
+                        if (data.selector === '#fullscreen-button') {
+                            //this.engine.switchFullscreen(false);
+                            if (!isFullscreen) {
+                                let requestFullScreen = viewerElement.requestFullscreen || /*viewerElement.parent.msRequestFullscreen || viewerElement.parent.mozRequestFullScreen ||*/ viewerElement.webkitRequestFullscreen;
+                                requestFullScreen.call(viewerElement);
+                            } else {
+                                let exitFullscreen = document.exitFullscreen || document.webkitExitFullscreen
+                                exitFullscreen.call(document);
+                            }
+
+                            isFullscreen = !isFullscreen;
+
+                        }
+
+                    }
+                    break;
+            }
+        });
+
+    }
+
     protected prepareContainerElement() {
     protected prepareContainerElement() {
         this.containerElement.style.position = 'relative';
         this.containerElement.style.position = 'relative';
         this.containerElement.style.display = 'flex';
         this.containerElement.style.display = 'flex';
@@ -55,6 +90,9 @@ export class DefaultViewer extends AbstractViewer {
 
 
     public onModelLoaded(meshes: Array<AbstractMesh>) {
     public onModelLoaded(meshes: Array<AbstractMesh>) {
 
 
+        // here we could set the navbar's model information:
+        this.setModelMetaData();
+
         this.hideLoadingScreen();
         this.hideLoadingScreen();
 
 
         // recreate the camera
         // recreate the camera
@@ -69,6 +107,28 @@ export class DefaultViewer extends AbstractViewer {
         return this.initEnvironment();
         return this.initEnvironment();
     }
     }
 
 
+    private setModelMetaData() {
+        let navbar = this.templateManager.getTemplate('navBar');
+
+        let metadataContainer = navbar.parent.querySelector('#model-metadata');
+
+        //title
+        if (typeof this.configuration.model === 'object') {
+            if (this.configuration.model.title) {
+                metadataContainer.querySelector('span.model-title').innerHTML = this.configuration.model.title;
+            }
+
+            if (this.configuration.model.subtitle) {
+                metadataContainer.querySelector('span.model-subtitle').innerHTML = this.configuration.model.subtitle;
+            }
+
+            if (this.configuration.model.thumbnail) {
+                (<HTMLDivElement>metadataContainer.querySelector('.thumbnail')).style.backgroundImage = `url('${this.configuration.model.thumbnail}')`;
+            }
+        }
+
+    }
+
     public initEnvironment(): Promise<Scene> {
     public initEnvironment(): Promise<Scene> {
         if (this.configuration.skybox) {
         if (this.configuration.skybox) {
             // Define a general environment textue
             // Define a general environment textue