Quick question, were you able to include files from the Examples folder from three?
I am using ionic2 and typescript 2. I tried a lot of things, and the thing that is close to work is this:
Installed imports-loader, created a three-loader.js:
const THREE = require('three');
window.THREE = THREE;
require('imports-loader?THREE=three!three/examples/js/renderers/CanvasRenderer');
module.export = THREE;
And imported it in my page.ts, with:
require('../../three-loader');
But, even if it bundles correctly the CanvasRenderer, Three.js is using it’s own function which is deprecated, as the CanvasRenderer has been externalized.
(But if I take a look in the generated main.js, with all the libraries… I can see that both functions are present: The one that comes from the build version of Three.js and the one injected by loading CanvasRenderer.
Only, THREE.CanvasRenderer does not reference the loaded CanvasRendererer module.
Any ideas?
PS: This is my TS Code (it’s just a three.js example ported to TypeScript variables, and, except for the CanvasRenderer Issue, it should work…)
import {Component} from '@angular/core';
import {MenuController, NavController} from 'ionic-angular';
import {WelcomePage} from '../welcome/welcome';
import {TranslateService} from 'ng2-translate/ng2-translate';
require('../../three-loader');
export interface Slide {
title: string;
description: string;
image: string;
}
@Component({
selector: 'page-tutorial',
templateUrl: 'tutorial.html'
})
export class TutorialPage {
slides: Slide[];
showSkip = true;
SEPARATION: number = 100;
AMOUNTX: number = 50;
AMOUNTY: number = 50;
container: any;
stats: any;
camera: any;
scene: any;
renderer: any;
particles: any;
particle: any;
count: number = 0;
mouseX: number = 0;
mouseY: number = 0;
windowHalfX: number = window.innerWidth / 2;
windowHalfY: number = window.innerHeight / 2;
constructor(public navCtrl: NavController, public menu: MenuController, translate: TranslateService) {
translate.get(["TUTORIAL_SLIDE1_TITLE",
"TUTORIAL_SLIDE1_DESCRIPTION",
"TUTORIAL_SLIDE2_TITLE",
"TUTORIAL_SLIDE2_DESCRIPTION",
"TUTORIAL_SLIDE3_TITLE",
"TUTORIAL_SLIDE3_DESCRIPTION",
])
.subscribe((values) => {
console.log('Loaded values', values);
this.slides = [
{
title: values.TUTORIAL_SLIDE1_TITLE,
description: values.TUTORIAL_SLIDE1_DESCRIPTION,
image: 'assets/img/ica-slidebox-img-1.png',
},
{
title: values.TUTORIAL_SLIDE2_TITLE,
description: values.TUTORIAL_SLIDE2_DESCRIPTION,
image: 'assets/img/ica-slidebox-img-2.png',
},
{
title: values.TUTORIAL_SLIDE3_TITLE,
description: values.TUTORIAL_SLIDE3_DESCRIPTION,
image: 'assets/img/ica-slidebox-img-3.png',
}
];
});
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
this.camera.position.z = 1000;
this.scene = new THREE.Scene();
this.particles = new Array();
var PI2 = Math.PI * 2;
var material = new THREE.SpriteCanvasMaterial({
color: 0xffffff,
program: function (context) {
context.beginPath();
context.arc(0, 0, 0.5, 0, PI2, true);
context.fill();
}
});
var i = 0;
for (var ix = 0; ix < this.AMOUNTX; ix++) {
for (var iy = 0; iy < this.AMOUNTY; iy++) {
this.particle = this.particles[i++] = new THREE.Sprite(material);
this.particle.position.x = ix * this.SEPARATION - ( ( this.AMOUNTX * this.SEPARATION ) / 2 );
this.particle.position.z = iy * this.SEPARATION - ( ( this.AMOUNTY * this.SEPARATION ) / 2 );
this.scene.add(this.particle);
}
}
this.renderer = new THREE.CanvasRenderer();
document.addEventListener('mousemove', this.onDocumentMouseMove, false);
document.addEventListener('touchstart', this.onDocumentTouchStart, false);
document.addEventListener('touchmove', this.onDocumentTouchMove, false);
window.addEventListener( 'resize', this.onWindowResize, false );
setTimeout(() => {
this.renderer.setSize(window.innerWidth, window.innerHeight);
//this.renderer.setPixelRatio = window.devicePixelRatio ;
this.container = document.getElementById('threeContent');
this.container.appendChild(this.renderer.domElement);
this.render();
}, 1);
}
onWindowResize() {
this.windowHalfX = window.innerWidth / 2;
this.windowHalfY = window.innerHeight / 2;
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
}
onDocumentMouseMove(event) {
this.mouseX = event.clientX - this.windowHalfX;
this.mouseY = event.clientY - this.windowHalfY;
}
onDocumentTouchStart(event) {
if (event.touches.length === 1) {
event.preventDefault();
this.mouseX = event.touches[0].pageX - this.windowHalfX;
this.mouseY = event.touches[0].pageY - this.windowHalfY;
}
}
onDocumentTouchMove(event) {
if (event.touches.length === 1) {
event.preventDefault();
this.mouseX = event.touches[0].pageX - this.windowHalfX;
this.mouseY = event.touches[0].pageY - this.windowHalfY;
}
}
//
animate() {
requestAnimationFrame(this.animate);
this.render();
this.stats.update();
}
render() {
this.camera.position.x += ( this.mouseX - this.camera.position.x ) * .05;
this.camera.position.y += ( -this.mouseY - this.camera.position.y ) * .05;
this.camera.lookAt(this.scene.position);
var i = 0;
for (var ix = 0; ix < this.AMOUNTX; ix++) {
for (var iy = 0; iy < this.AMOUNTY; iy++) {
this.particle = this.particles[i++];
this.particle.position.y = ( Math.sin(( ix + this.count ) * 0.3) * 50 ) +
( Math.sin(( iy + this.count ) * 0.5) * 50 );
this.particle.scale.x = this.particle.scale.y = ( Math.sin(( ix + this.count ) * 0.3) + 1 ) * 4 +
( Math.sin(( iy + this.count ) * 0.5) + 1 ) * 4;
}
}
this.renderer.render(this.scene, this.camera);
this.count += 0.1;
}
startApp() {
this.navCtrl.setRoot(WelcomePage, {}, {
animate: true,
direction: 'forward'
});
}
onSlideChangeStart(slider) {
this.showSkip = !slider.isEnd;
}
ionViewDidEnter() {
// the root left menu should be disabled on the tutorial page
this.menu.enable(false);
}
ionViewWillLeave() {
// enable the root left menu when leaving the tutorial page
this.menu.enable(true);
}
}
It is a pain that this other components are not modularized. And If you have any workaround to successfully load them… that would be great.
Thanks!