Преглед изворни кода

Merge pull request #3058 from RaananW/viewer-changes

Further viewer changes
Raanan Weber пре 7 година
родитељ
комит
dbe7feeece

+ 1 - 4
Viewer/dist/basicExample.html

@@ -18,11 +18,8 @@
 
     <body>
         <babylon model.title="Amazing Rabbit" model.subtitle="BabylonJS" model.thumbnail="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png"
-            model.url="https://playground.babylonjs.com/scenes/Rabbit.babylon" default-viewer="true" templates.nav-bar.params.disable-on-fullscreen="true"></babylon>
+            model.url="https://playground.babylonjs.com/scenes/Rabbit.babylon" camera.behaviors.auto-rotate="0" templates.nav-bar.params.disable-on-fullscreen="true"></babylon>
         <script src="viewer.js"></script>
     </body>
 
-</html>
-<html>
-
 </html>

+ 5 - 5
Viewer/dist/domExample.html

@@ -20,16 +20,16 @@
                 subtitle="Remix3D" thumbnail="http://d33wubrfki0l68.cloudfront.net/7e08139ddee0ec38005f4232346c7f7386831300/fd934/githubuniverse/remix3d.png">
             </model>
             <camera>
-                <behaviors array="true">
-                    <behavior type="0"></behavior>
+                <behaviors>
+                    <auto-rotate type="0"></auto-rotate>
                 </behaviors>
             </camera>
-            <lights array="true">
-                <light type="1" shadow-enabled="true" position.y="0.5" direction.y="-1" intensity="4.5">
+            <lights>
+                <light1 type="1" shadow-enabled="true" position.y="0.5" direction.y="-1" intensity="4.5">
                     <shadow-config use-blur-exponential-shadow-map="true" use-kernel-blur="true" blur-kernel="64" blur-scale="4">
 
                     </shadow-config>
-                </light>
+                </light1>
             </lights>
         </babylon>
         <script src="viewer.js"></script>

+ 37 - 24
Viewer/dist/viewer.js

@@ -74299,7 +74299,7 @@ var TemplateManager = (function () {
             }
             return template;
         };
-        var htmlTree = this.buildHTMLTree(templates).then(function (htmlTree) {
+        this.buildHTMLTree(templates).then(function (htmlTree) {
             internalInit(htmlTree, 'main');
         });
     };
@@ -74308,6 +74308,7 @@ var TemplateManager = (function () {
         var promises = Object.keys(templates).map(function (name) {
             var template = new Template(name, templates[name]);
             _this.templates[name] = template;
+            return template.initPromise;
         });
         return Promise.all(promises).then(function () {
             var templateStructure = {};
@@ -74375,8 +74376,12 @@ var Template = (function () {
     });
     Template.prototype.getChildElements = function () {
         var childrenArray = [];
-        for (var i = 0; i < this.fragment.children.length; ++i) {
-            childrenArray.push(helper_1.kebabToCamel(this.fragment.children.item(i).nodeName.toLowerCase()));
+        var children = this.fragment.children;
+        if (!children) {
+            children = this.fragment.querySelectorAll('*');
+        }
+        for (var i = 0; i < children.length; ++i) {
+            childrenArray.push(helper_1.kebabToCamel(children.item(i).nodeName.toLowerCase()));
         }
         return childrenArray;
     };
@@ -74428,23 +74433,31 @@ var Template = (function () {
     Template.prototype.registerEvents = function () {
         var _this = this;
         if (this._configuration.events) {
-            Object.keys(this._configuration.events).forEach(function (eventName) {
-                if (_this._configuration.events && _this._configuration.events[eventName]) {
+            var _loop_1 = function (eventName) {
+                if (this_1._configuration.events && this_1._configuration.events[eventName]) {
                     var functionToFire_1 = function (selector, event) {
                         _this.onEventTriggered.notifyObservers({ event: event, template: _this, selector: selector });
                     };
-                    if (typeof _this._configuration.events[eventName] === 'boolean') {
-                        _this.parent.addEventListener(eventName, functionToFire_1.bind(_this, '#' + _this.parent.id), false);
+                    if (typeof this_1._configuration.events[eventName] === 'boolean') {
+                        this_1.parent.addEventListener(eventName, functionToFire_1.bind(this_1, '#' + this_1.parent.id), false);
                     }
-                    else {
-                        var selectorsArray = _this._configuration.events[eventName];
-                        selectorsArray.forEach(function (selector) {
+                    else if (typeof this_1._configuration.events[eventName] === 'object') {
+                        var selectorsArray = Object.keys(this_1._configuration.events[eventName] || {});
+                        var event_1 = this_1._configuration.events[eventName] || {};
+                        selectorsArray.filter(function (selector) { return event_1[selector]; }).forEach(function (selector) {
+                            if (selector.indexOf('#') !== 0) {
+                                selector = '#' + selector;
+                            }
                             var htmlElement = _this.parent.querySelector(selector);
                             htmlElement && htmlElement.addEventListener(eventName, functionToFire_1.bind(_this, selector), false);
                         });
                     }
                 }
-            });
+            };
+            var this_1 = this;
+            for (var eventName in this._configuration.events) {
+                _loop_1(eventName);
+            }
         }
     };
     return Template;
@@ -100860,7 +100873,7 @@ exports.defaultConfiguration = {
                 visibilityTimeout: 2000
             },
             events: {
-                pointerdown: ['#fullscreen-button']
+                pointerdown: { 'fullscreen-button': true }
             }
         },
         overlay: {
@@ -100881,14 +100894,14 @@ exports.defaultConfiguration = {
         }
     },
     camera: {
-        behaviors: [
-            0,
-            {
+        behaviors: {
+            autoRotate: 0,
+            framing: {
                 type: 2,
                 zoomOnBoundingInfo: true,
                 zoomStopsAnimation: false
             }
-        ]
+        }
     },
     skybox: {
         cubeTexture: {
@@ -103372,7 +103385,7 @@ var DefaultViewer = (function (_super) {
                         switch (data.selector) {
                             case '#fullscreen-button':
                                 if (!isFullscreen) {
-                                    var requestFullScreen = viewerElement.requestFullscreen || viewerElement.webkitRequestFullscreen;
+                                    var requestFullScreen = viewerElement.requestFullscreen || viewerElement.webkitRequestFullscreen || viewerElement.msRequestFullscreen || viewerElement.mozRequestFullScreen;
                                     requestFullScreen.call(viewerElement);
                                 }
                                 else {
@@ -103536,12 +103549,13 @@ var DefaultViewer = (function (_super) {
         var _this = this;
         if (focusMeshes === void 0) { focusMeshes = []; }
         var sceneConfig = this.configuration.scene || { defaultLight: true };
-        if (!sceneConfig.defaultLight && (this.configuration.lights && this.configuration.lights.length)) {
+        if (!sceneConfig.defaultLight && (this.configuration.lights && Object.keys(this.configuration.lights).length)) {
             this.scene.lights.forEach(function (l) {
                 l.dispose();
             });
-            this.configuration.lights.forEach(function (lightConfig, idx) {
-                lightConfig.name = lightConfig.name || 'light-' + idx;
+            Object.keys(this.configuration.lights).forEach(function (name, idx) {
+                var lightConfig = _this.configuration.lights && _this.configuration.lights[name] || { name: name, type: 0 };
+                lightConfig.name = name;
                 var constructor = babylonjs_1.Light.GetConstructorFromName(lightConfig.type, lightConfig.name, _this.scene);
                 var light = constructor();
                 if (light.isEnabled() !== !lightConfig.disabled) {
@@ -103561,7 +103575,6 @@ var DefaultViewer = (function (_super) {
         }
     };
     DefaultViewer.prototype.setupCamera = function (focusMeshes) {
-        var _this = this;
         if (focusMeshes === void 0) { focusMeshes = []; }
         var sceneConfig = this.configuration.scene || { autoRotate: false, defaultCamera: true };
         if (sceneConfig.defaultCamera) {
@@ -103577,9 +103590,9 @@ var DefaultViewer = (function (_super) {
         this.camera.minZ = cameraConfig.minZ || this.camera.minZ;
         this.camera.maxZ = cameraConfig.maxZ || this.camera.maxZ;
         if (cameraConfig.behaviors) {
-            cameraConfig.behaviors.forEach(function (behaviorConfig) {
-                _this.setCameraBehavior(behaviorConfig, focusMeshes);
-            });
+            for (var name_1 in cameraConfig.behaviors) {
+                this.setCameraBehavior(cameraConfig.behaviors[name_1], focusMeshes);
+            }
         }
         ;
         if (sceneConfig.autoRotate) {

+ 40 - 34
Viewer/src/configuration/configuration.ts

@@ -62,10 +62,12 @@ export interface ViewerConfiguration {
         minZ?: number;
         maxZ?: number;
         inertia?: number;
-        behaviors?: Array<number | {
-            type: number;
-            [propName: string]: any;
-        }>;
+        behaviors?: {
+            [name: string]: number | {
+                type: number;
+                [propName: string]: any;
+            };
+        };
 
         [propName: string]: any;
     },
@@ -93,33 +95,37 @@ export interface ViewerConfiguration {
             [propName: string]: any;
         }
     };
-    lights?: Array<{
-        type: number;
-        name?: string;
-        disabled?: boolean;
-        position?: { x: number, y: number, z: number };
-        target?: { x: number, y: number, z: number };
-        direction?: { x: number, y: number, z: number };
-        diffuse?: { r: number, g: number, b: number };
-        specular?: { r: number, g: number, b: number };
-        intensity?: number;
-        radius?: number;
-        shadownEnabled?: boolean; // only on specific lights!
-        shadowConfig?: {
-            useBlurExponentialShadowMap?: boolean;
-            useKernelBlur?: boolean;
-            blurKernel?: number;
-            blurScale?: number;
-            [propName: string]: any;
-        }
-        [propName: string]: any;
-
-        // no behaviors for light at the moment, but allowing configuration for future reference.
-        behaviors?: Array<number | {
+    lights?: {
+        [name: string]: {
             type: number;
+            name?: string;
+            disabled?: boolean;
+            position?: { x: number, y: number, z: number };
+            target?: { x: number, y: number, z: number };
+            direction?: { x: number, y: number, z: number };
+            diffuse?: { r: number, g: number, b: number };
+            specular?: { r: number, g: number, b: number };
+            intensity?: number;
+            radius?: number;
+            shadownEnabled?: boolean; // only on specific lights!
+            shadowConfig?: {
+                useBlurExponentialShadowMap?: boolean;
+                useKernelBlur?: boolean;
+                blurKernel?: number;
+                blurScale?: number;
+                [propName: string]: any;
+            }
             [propName: string]: any;
-        }>
-    }>
+
+            // no behaviors for light at the moment, but allowing configuration for future reference.
+            behaviors?: {
+                [name: string]: number | {
+                    type: number;
+                    [propName: string]: any;
+                };
+            };
+        }
+    },
     // engine configuration. optional!
     engine?: {
         antialiasing?: boolean;
@@ -210,7 +216,7 @@ export let defaultConfiguration: ViewerConfiguration = {
                 disableOnFullscreen: false*/
             },
             events: {
-                pointerdown: ['#fullscreen-button'/*, '#help-button'*/]
+                pointerdown: { 'fullscreen-button': true/*, '#help-button': true*/ }
             }
         },
         overlay: {
@@ -232,14 +238,14 @@ export let defaultConfiguration: ViewerConfiguration = {
 
     },
     camera: {
-        behaviors: [
-            0,
-            {
+        behaviors: {
+            autoRotate: 0,
+            framing: {
                 type: 2,
                 zoomOnBoundingInfo: true,
                 zoomStopsAnimation: false
             }
-        ]
+        }
     },
     /*lights: [
         {

+ 1 - 1
Viewer/src/configuration/mappers.ts

@@ -22,7 +22,7 @@ class HTMLMapper implements IMapper {
                 //convert html-style to json-style
                 let camelKey = kebabToCamel(key);
                 if (idx === split.length - 1) {
-                    let val: any = attr.nodeValue;
+                    let val: any = attr.nodeValue; // firefox warns nodeValue is deprecated, but I found no sign of it anywhere.
                     if (val === "true") {
                         val = true;
                     } else if (val === "false") {

+ 32 - 20
Viewer/src/templateManager.ts

@@ -9,21 +9,21 @@ export interface ITemplateConfiguration {
     params?: { [key: string]: string | number | boolean | object };
     events?: {
         // pointer events
-        pointerdown?: boolean | Array<string>;
-        pointerup?: boolean | Array<string>;
-        pointermove?: boolean | Array<string>;
-        pointerover?: boolean | Array<string>;
-        pointerout?: boolean | Array<string>;
-        pointerenter?: boolean | Array<string>;
-        pointerleave?: boolean | Array<string>;
-        pointercancel?: boolean | Array<string>;
+        pointerdown?: boolean | { [id: string]: boolean; };
+        pointerup?: boolean | { [id: string]: boolean; };
+        pointermove?: boolean | { [id: string]: boolean; };
+        pointerover?: boolean | { [id: string]: boolean; };
+        pointerout?: boolean | { [id: string]: boolean; };
+        pointerenter?: boolean | { [id: string]: boolean; };
+        pointerleave?: boolean | { [id: string]: boolean; };
+        pointercancel?: boolean | { [id: string]: boolean; };
         //click, just in case
-        click?: boolean | Array<string>;
+        click?: boolean | { [id: string]: boolean; };
         // drag and drop
-        dragstart?: boolean | Array<string>;
-        drop?: boolean | Array<string>;
+        dragstart?: boolean | { [id: string]: boolean; };
+        drop?: boolean | { [id: string]: boolean; };
 
-        [key: string]: boolean | Array<string> | undefined;
+        [key: string]: boolean | { [id: string]: boolean; } | undefined;
     }
 }
 
@@ -83,7 +83,7 @@ export class TemplateManager {
         }
 
         //build the html tree
-        let htmlTree = this.buildHTMLTree(templates).then(htmlTree => {
+        this.buildHTMLTree(templates).then(htmlTree => {
             internalInit(htmlTree, 'main');
         });
     }
@@ -102,6 +102,7 @@ export class TemplateManager {
         let promises = Object.keys(templates).map(name => {
             let template = new Template(name, templates[name]);
             this.templates[name] = template;
+            return template.initPromise;
         });
 
         return Promise.all(promises).then(() => {
@@ -196,8 +197,14 @@ export class Template {
 
     public getChildElements(): Array<string> {
         let childrenArray: string[] = [];
-        for (let i = 0; i < this.fragment.children.length; ++i) {
-            childrenArray.push(kebabToCamel(this.fragment.children.item(i).nodeName.toLowerCase()));
+        //Edge and IE don't support frage,ent.children
+        let children = this.fragment.children;
+        if (!children) {
+            // casting to HTMLCollection, as both NodeListOf and HTMLCollection have 'item()' and 'length'.
+            children = <HTMLCollection>this.fragment.querySelectorAll('*');
+        }
+        for (let i = 0; i < children.length; ++i) {
+            childrenArray.push(kebabToCamel(children.item(i).nodeName.toLowerCase()));
         }
         return childrenArray;
     }
@@ -251,7 +258,7 @@ export class Template {
     // TODO - Should events be removed as well? when are templates disposed?
     private registerEvents() {
         if (this._configuration.events) {
-            Object.keys(this._configuration.events).forEach(eventName => {
+            for (let eventName in this._configuration.events) {
                 if (this._configuration.events && this._configuration.events[eventName]) {
                     let functionToFire = (selector, event) => {
                         this.onEventTriggered.notifyObservers({ event: event, template: this, selector: selector });
@@ -260,15 +267,20 @@ export class Template {
                     // if boolean, set the parent as the event listener
                     if (typeof this._configuration.events[eventName] === 'boolean') {
                         this.parent.addEventListener(eventName, functionToFire.bind(this, '#' + this.parent.id), false);
-                    } else {
-                        let selectorsArray: Array<string> = <Array<string>>this._configuration.events[eventName];
-                        selectorsArray.forEach(selector => {
+                    } else if (typeof this._configuration.events[eventName] === 'object') {
+                        let selectorsArray: Array<string> = Object.keys(this._configuration.events[eventName] || {});
+                        // strict null checl is working incorrectly, must override:
+                        let event = this._configuration.events[eventName] || {};
+                        selectorsArray.filter(selector => event[selector]).forEach(selector => {
+                            if (selector.indexOf('#') !== 0) {
+                                selector = '#' + selector;
+                            }
                             let htmlElement = <HTMLElement>this.parent.querySelector(selector);
                             htmlElement && htmlElement.addEventListener(eventName, functionToFire.bind(this, selector), false)
                         });
                     }
                 }
-            });
+            }
         }
     }
 

+ 8 - 7
Viewer/src/viewer/defaultViewer.ts

@@ -90,7 +90,7 @@ export class DefaultViewer extends AbstractViewer {
                         switch (data.selector) {
                             case '#fullscreen-button':
                                 if (!isFullscreen) {
-                                    let requestFullScreen = viewerElement.requestFullscreen || viewerElement.webkitRequestFullscreen; // || viewerElement.parent.msRequestFullscreen || viewerElement.parent.mozRequestFullScreen 
+                                    let requestFullScreen = viewerElement.requestFullscreen || viewerElement.webkitRequestFullscreen || (<any>viewerElement).msRequestFullscreen || (<any>viewerElement).mozRequestFullScreen;
                                     requestFullScreen.call(viewerElement);
                                 } else {
                                     let exitFullscreen = document.exitFullscreen || document.webkitExitFullscreen
@@ -299,14 +299,15 @@ export class DefaultViewer extends AbstractViewer {
 
         let sceneConfig = this.configuration.scene || { defaultLight: true };
 
-        if (!sceneConfig.defaultLight && (this.configuration.lights && this.configuration.lights.length)) {
+        if (!sceneConfig.defaultLight && (this.configuration.lights && Object.keys(this.configuration.lights).length)) {
             // remove old lights
             this.scene.lights.forEach(l => {
                 l.dispose();
             });
 
-            this.configuration.lights.forEach((lightConfig, idx) => {
-                lightConfig.name = lightConfig.name || 'light-' + idx;
+            Object.keys(this.configuration.lights).forEach((name, idx) => {
+                let lightConfig = this.configuration.lights && this.configuration.lights[name] || { name: name, type: 0 };
+                lightConfig.name = name;
                 let constructor = Light.GetConstructorFromName(lightConfig.type, lightConfig.name, this.scene);
                 let light = constructor();
 
@@ -354,9 +355,9 @@ export class DefaultViewer extends AbstractViewer {
         this.camera.maxZ = cameraConfig.maxZ || this.camera.maxZ;
 
         if (cameraConfig.behaviors) {
-            cameraConfig.behaviors.forEach((behaviorConfig) => {
-                this.setCameraBehavior(behaviorConfig, focusMeshes);
-            });
+            for (let name in cameraConfig.behaviors) {
+                this.setCameraBehavior(cameraConfig.behaviors[name], focusMeshes);
+            }
         };
 
         if (sceneConfig.autoRotate) {