There is an unusual behavior in the x3d element inserted into an Angular (version 4) component that I have observed.
The structure of my Angular project is as follows:
x3d_and_angular/
app/
home/
home.component.css
home.component.html
home.component.ts
index.ts
viewer/
viewer.component.css
viewer.component.html
viewer.component.ts
index.ts
app.component.html
app.component.ts
app.module.ts
app.routing.ts
main.ts
app.css
index.html
package.json
red_box.x3d
sysytemjs.config.js
I included the x3dom
library in both package.json
and sysytemjs.config.js
.
This is how my index.html
looks like:
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>X3D and Angular Integration</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- bootstrap css -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<link rel='stylesheet' type='text/css' href='http://www.x3dom.org/download/x3dom.css'>
<!-- application css -->
<link href="app.css" rel="stylesheet" />
<!-- polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function (err) { console.error(err); });
</script>
<script>
function show_inline_url(){
console.log(document.getElementById("inline_element"));
}
</script>
</head>
<body>
<app>Loading ...</app>
</body>
</html>
The X3D file (red_box.x3d
) that displays a small red box has the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "http://www.web3d.org/specifications/x3d-3.3.dtd">
<x3d>
<head>
<meta name="title"/>
</head>
<Scene>
<Shape id="shape_id">
<appearance>
<material diffuseColor='1 0 0'></material>
</appearance>
<box></box>
</Shape>
</Scene>
</x3d>
Here is the code for the home
component:
home.component.html
:<div> <a [routerLink]="['/viewer']">X3D Viewer</a> </div>
home.component.ts
:import { Component, OnInit } from '@angular/core'; @Component({ moduleId: module.id, templateUrl: 'home.component.html', styleUrls: ['home.component.css'], }) export class HomeComponent{ constructor() { } }
The issue arises in the viewer
component. Below are the files associated with this component:
viewer.component.html
:<div> <x3d width='600px' height='400px'> <scene> <inline id="inline_element" [url]="x3d_filename"> </inline> </scene> <a [routerLink]="['/']"><span>BACK</span></a> </x3d> </div>
viewer.component.ts
:import { Component, OnInit } from '@angular/core'; declare var System: any; @Component({ moduleId: module.id, templateUrl: 'viewer.component.html', styleUrls: ['viewer.component.css'], }) export class ViewerComponent implements OnInit{ x3d_filename: string = "red_box.x3d"; constructor() { this.importX3d(); } ngOnInit(){ if(window["x3dom"] != undefined){ window["x3dom"].reload(); } } importX3d():void{ System.import('x3dom').then(() => { console.log('loaded x3d'); }).catch((e:any) => { console.warn(e); }) } }
The routing of my Angular application goes from the home
component to the viewer
component and vice versa. These routes are defined in the app.routing.ts
file:
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/index';
import { ViewerComponent } from './viewer/index';
const appRoutes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'viewer', component: ViewerComponent},
// otherwise redirect to home
{ path: '**', redirectTo: '' }
];
export const routing = RouterModule.forRoot(appRoutes);
Upon refreshing the website, when accessing the viewer
component for the first time, the scene appears empty. However, subsequent visits to this component through routing (without refreshing) result in the box being rendered inside the scene.
Replacing the inline
tag in the viewer.component.html
file with
<inline url="red_box.x3d"> </inline>
eliminates this issue (the box is rendered even on the first visit after a refresh).
If anyone has suggestions on how to resolve this peculiar behavior, I would greatly appreciate it. I am relatively new to Angular and web development, so any assistance is welcomed. Thank you.