Using Three.js with WebStorm, module import not working - three.js

Not usually a JS programmer. I setup a new WebStorm project, used npm to install three.js, everything looks fine, but when I try to import it the import statement is fine, but you can't use it, nothing is code completed.
Clearly I am missing something important. Three appears correctly in the package.json and lock json and I have all the files in the usual node_modules. Any use of the import THREE shows nothing. There are no errors, just warnings about the unused items and WebGLRenderer is undefined.
This is the default WebStorm setup with ECMAScript 6.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script type="module">
import * as THREE from 'three';
function main()
{
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
}
</script>
<canvas id="c"></canvas>
</body>
</html>

Restarting Webstorm made it work again. The app was running for a couple weeks, so perhaps there is memory leak or other issue.

Related

How to integrate threejs modules with Aframe?

So I find a lot of interesting scripts that are built just with threejs, but I would like to somehow combine them with the ease of use that Aframe provides.
The below code starts by importing three.module.js - which I believe is already bundled with Aframe, so how can I include/import the required files and use them within a component?
I have had some joy including the three.module.js in my files and loading it exactly as below, but this seems like an unnecessary requirement/duplication of code.
<script type="module">
import * as THREE from '../build/three.module.js';
import { GUI } from './jsm/libs/dat.gui.module.js';
import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
import { RenderPass } from './jsm/postprocessing/RenderPass.js';
import { AfterimagePass } from './jsm/postprocessing/AfterimagePass.js';
EDIT:
Think I may be slowly getting there
<script src="./scripts/Pass.js"></script>
<script src="./scripts/CopyShader.js"></script>
<script src="./scripts/ShaderPass.js"></script>
<script src="./scripts/EffectComposer.js"></script>
<script src="./scripts/RenderPass.js"></script>
<script src="./scripts/AfterImageShader.js"></script>
<script src="./scripts/AfterImagePass.js"></script>
<script>
let composer;
let mesh;
let afterimagePass;
document.querySelector('a-scene').addEventListener('loaded', function () {
console.log(sceneEl.renderer.getSize());
composer = new THREE.EffectComposer( sceneEl.renderer );
composer.addPass( new THREE.RenderPass( sceneEl, sceneEl.camera ) );
afterimagePass = new THREE.AfterimagePass();
composer.addPass( afterimagePass );
composer.render(sceneEl, sceneEl.camera);
});
</script>
But now it's throwing this error
three.js:19204 Uncaught TypeError: t.onBeforeRender is not a function
at qe.render (three.js:19204)
at RenderPass.render (RenderPass.js:52)
at EffectComposer.render (EffectComposer.js:123)
at HTMLElement.<anonymous> ((index):982)
at HTMLElement.<anonymous> (a-node.js:263)
at a-node.js:128
Three.js doesn't currently support post processing for VR (https://github.com/mrdoob/three.js/pull/15840). While you might be able to get post processing to work in A-Frame using the default 2D camera, it currently breaks as soon as you switch to VR or AR -- this is due to the Three.js dependency, not A-Frame itself. To get 2D post processing to work in A-Frame you might try binding the EffectComposer to the A-Frame render loop (https://gist.github.com/donmccurdy/31560945d5723737e6c656a2974ab628).

Application in augmente reality

I have this project about development of an augmented reality application to train firefighters with three js. I managed to create the fire scene, now the problem is i have to add a dynamic aspect to the programmed solution so as to represent the propagation of the fire as a function of the elapsed time.
Here is below my scilab program , the propagation have to follow this model. now i've been told that i have to search how to manipulate vertices of a geometry and manipulate them with the VECTOR3 on three js but i didnt know how to solve it. any help is appreciated
scilab program
and this is the code for the fire, i ran it on visual basic Fire
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>fire fire</title>
<style>
body{margin: 0; background: #333;}
canvas{display: block;}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.js"></script>
<script src="../dist/three-particle-fire.js"></script>
<script>
//
// prepare to use
//
particleFire.install( { THREE: THREE } );
var width  = window.innerWidth,   
    height = window.innerHeight,
    clock = new THREE.Clock(),
    scene,
    camera,
    renderer,
    loader = new THREE.JSONLoader(),
    textureLoader = new THREE.TextureLoader();
scene  = new THREE.Scene();//
scene.fog = new THREE.Fog( 0x333333, 8, 20 );
camera = new THREE.PerspectiveCamera( 40, width / height, 0.1, 100 );
camera.position.z = 10;
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( width, height );
renderer.setClearColor( 0x333333 );
renderer.setPixelRatio( window.devicePixelRatio );
document.body.appendChild( renderer.domElement );
scene.add( new THREE.DirectionalLight( 0xffffff ) );
scene.add( new THREE.AmbientLight( 0x666666 ) );
var fireRadius = 2;// 43 45 parametre de la geometry fire
var fireHeight = 20;
var particleCount = 5200;
/
var geometry0 = new particleFire.Geometry( fireRadius, fireHeight, particleCount ); 
var material0 = new particleFire.Material( { color: 0xff2200 , wireframe: true } );
material0.setPerspective( camera.fov, height );
var particleFireMesh0 = new THREE.Points( geometry0, material0 );
particleFireMesh0.position.set( 0, -1, 0 );
scene.add( particleFireMesh0 );






var groundColor = textureLoader.load( 'grass_diffuse.png' );//85  95 creation ground et l ajouter a la scene
groundColor.repeat.set( 10, 10 );
groundColor.wrapS = groundColor.wrapT = THREE.RepeatWrapping;
var ground = new THREE.Mesh(
    new THREE.PlaneBufferGeometry( 50, 50, 1, 1 ),
    new THREE.MeshPhongMaterial( { map: groundColor } )
);
ground.position.y = -1;
ground.rotation.x = THREE.Math.degToRad( -90 );
scene.add( ground );
particleFire = [];
( function update () {
    var delta = clock.getDelta();
    var elapsed = clock.getElapsedTime(); 
  particleFireMesh0.geometry.verticesNeedUpdate = true; 
  
    requestAnimationFrame( update );
    particleFireMesh0.material.update( delta * 0.1 );  
    
    camera.position.set(6,5,10);
    camera.lookAt( particleFireMesh0.position );
    renderer.render( scene, camera );
} )();
window.addEventListener( 'resize', function () {
    var width  = window.innerWidth;
    var height = window.innerHeight;
    camera.aspect = width / height;
    camera.updateProjectionMatrix();
    renderer.setSize( width, height );
    particleFireMesh0.material.setPerspective( camera.fov, height );
    //particleFireMesh1.material.setPerspective( camera.fov, height );//
    
} );
console.log("vertices: ", geometry0.vertices);
console.log( geometry0.isBufferGeometry );
  
</script>
</body>
</html>

How to communicate 'externally' between Adobe Animate CC animations?

From the script in the html page, I'm trying to control what happens in the Adobe Animate CC animations I've created. For example, here you'll see a script that doesn't work that's trying to tell the ship animation to gotoAndPlay(5). Anyhow, the ship animation is not responding to that. I'm guessing it's because I'm not addressing/naming it correctly. Help me talk to my animations. See the code below.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Lets talk to each other</title>
<script src="http://code.createjs.com/easeljs-0.8.1.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.6.1.min.js"></script>
<script src="http://code.createjs.com/movieclip-0.8.1.min.js"></script>
<script src="ship.js"></script>
<script src="car.js"></script>
<script>
function init () {
var canvas, stage, exportRoot;
canvas = document.getElementById("canvas_ship");
exportRoot = new libs_ship.ship();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(libs_ship.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
canvas = document.getElementById("canvas_car");
exportRoot = new libs_car.car();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(libs_car.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
}
function Tell_Canvas_Ship_to_gotoAndPlay5(){
canvas_ship.gotoAndPlay(5);
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4">
<canvas id="canvas_ship" width="300" height="250" style="background-color:#FFFFFF"></canvas>
<canvas id="canvas_car" width="300" height="250" style="background-color:#FFFFFF"></canvas>
</body>
</html>
It looks like "canvas_ship" is the ID of your actual canvas element. I think what you are trying to do is control the content you are adding to it.
If so, you can call gotoAndPlay on the exportRoot, which is a MovieClip instance with that API.
exportRoot.gotoAndPlay(5);
The issue you will have though, is that once you create your canvas_ship stage and content, you are overwriting the variables. I recommend changing the name of the second canvas, exportRoot, and stage.
You could also add both elements to one canvas. Is there any reason you are using two canvases, other than that you used the exported content from 2 FLAs?
var stage = new createjs.Stage("canvas_ship");
var ship = new libs_ship.ship();
var car = new libs_car.car();
stage.addChild(ship, car);
createjs.Ticker.addEventListener("tick", stage);
Where is your Tell_Canvas_Ship_to_gotoAndPlay5 method getting called from? Is it a frame script in Animate/Flash?
I've received help and will now share the answer. You are welcome. Just invite me over for breakfast sometime.
In Adobe Animate, you'll need to change the library namespace (in the Publish settings in the Advanced tab I think) to lib_jerry or whatever custom name you come up with... so long as it's different than the other animation. Then just follow the setup in this code. You can call the functions from within the Animate animations.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Container</title>
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script src="tommy.js"></script>
<script src="jerry.js"></script>
<script>
var canvas, stage, tomtom, jerjer;
function init() {
var exportRoot;
//Tommy
canvas = document.getElementById("canvas_tommy");
tomtom = new lib_tommy.tommy();
stage = new createjs.Stage(canvas);
stage.addChild(tomtom);
stage.update();
createjs.Ticker.setFPS(lib_tommy.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
//Jerry
canvas = document.getElementById("canvas_jerry");
jerjer = new lib_jerry.jerry();
stage = new createjs.Stage(canvas);
stage.addChild(jerjer);
stage.update();
createjs.Ticker.setFPS(lib_jerry.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
}
function button_from_tommy_was_clicked(){
tomtom.gotoAndPlay(5);
}
function button_from_jerry_was_clicked(){
jerjer.gotoAndPlay(5);
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4;margin:0px;">
<canvas id="canvas_tommy" width="970" height="90" style="background-color:#727272"></canvas>
<canvas id="canvas_jerry" width="970" height="90" style="background-color:#727272"></canvas>
</body>
</html>

Troubleshooting Grid Toggle

Following the Visualizing Your Grids https://github.com/Team-Sass/Singularity/wiki/Creating-Grids#visualizing-your-grids instructions, I've been attempting to get the toggling functionality to work.
First off, can someone explain what the following is actually suppose to do?
compass install singularitygs/grid-toggle
I am assuming create a folder and some files, but when I run the command, nothing happens. If I do the following..
compass install singularitygs/box-sizing
It creates directories and files as expected.
My project works fine with Singularity (this is just 1 SASS file, 1 html file)
#include background-grid works within the SCSS file, but that's the first way of doing it and I'm interested in the toggle version.
I have tried to manually include the grid.js AND grid.min.js file provided and referenced them in the head of my index.html file. I added the data-development-grid="show" to the body tag as suggested. I can't even get the grid to show by default, let alone getting it to work with the toggle.
Here is part of my gem file
gem 'toolkit', '~>1.0.0'
gem 'singularitygs', '~>1.0.7'
gem 'breakpoint', '~>2.0.2'
group :development do
gem 'guard'
gem 'guard-compass'
gem 'guard-livereload'
end
And my simple HTML file
<html>
<head>
<link rel="stylesheet" type="text/css" href="stylesheets/screen.css" />
<script type="text/javascript" src="javascripts/grid.min.js"></script>
<script type="text/javascript" src="javascripts/grid.js"></script>
</head>
<body data-development-grid="show">
<h1>test</h1>
<div id="mydiv" class="no-mqs container">
<p>This is my div</p>
</div>
</body>
</html>
And my 1 SCSS file
#import 'compass';
#import 'compass/reset';
#import 'toolkit';
#import 'singularitygs';
#import 'breakpoint';
There are some grid variables, a container class, some other basic styles below all of the above imports.
Any help appreciated.
Thanks
The quick answer is to refer you to my question and answer on the same topic, about two questions ago. However, basically, there are three ways. The first you have found and you can place '#include background-grid' in the element that you wish to have a grid shown. I think you will find that you can't install grid-toggle, as directed, but I don't think you need to. The second method is the toggle. You have to place '#include grid-toggle' in your style.scss in either a * { ... } selector or an html{ ... } selector. You reference the script grid.js in the head of your web page. However, that script assumes you want the grid on your body div. You add data-development-grid="show" (or "hide") inside the body opening div.
You can put the grid on another element such as a wrap div (don't we all use wrap?), by adding data-development-grid="show" to the wrap div, but then you need to modify the grid.js file. Here is my javascript version as a guide (seems to work, but I'm no programmer!):
(function() {
window.onload = function() {
var body = document.body;
body.onkeypress = function(e) {
if (e.keyCode === 103 || e.charCode === 103) {
var wrap = document.getElementById('wrap');
var dev = wrap.getAttribute('data-development-grid');
if (dev === null || dev === 'hide') {
wrap.setAttribute('data-development-grid', 'show');
}
else {
wrap.setAttribute('data-development-grid', 'hide');
}
}
};
};
})();
BTW, your body or wrap (whichever you choose) must not have a background colour or image because the grid will be underneath and therefore invisible.
The third method is the overlay, which I particularly like because it sits over the background colour. for this, add #include grid-overlay('#wrap'); to the *{ ...} or html{ ... } element in your style.scss file. You will get a 4-line symbol in the bottom left and when you mouseover it, it causes the grid to appear - mouseoff = disappear.
I've assumed that you want the grid in a wrap div, but you can put it where you like.
I hope this helps.
For me it worked using the command: bundle exec compass install singularitygs/grid-toggle

controlling google earth with a controling application

If I were to write an application that controls another application which I don't have the binaries to,
For example, an application that by itself would open Google Earth and place the camera in a specific point my application would tell it, say -24,131, and then command google earth to save the image to a specific folder.
What is the approach to this?
How can I know the functions that are being executed and fire them on behalf of a control program like that?
Also, I will also need to know that downloading of images was finished so I can grab the image.
I saw there is an API for google earth, but I don't know if I can use it to control google-earth (the application itself)
You can use the Google Earth API (developers.google.com/earth/) to control a Google Earth globe instance.
See Javascript code snapshot here:
var ge;
google.load("earth", "1");
function init() {
google.earth.createInstance('map3d', initCB, failureCB);
}
function initCB(instance) {
ge = instance;
ge.getWindow().setVisibility(true);
ge.getOptions().setStatusBarVisibility(true);
ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);
var lookAt = ge.createLookAt('');
lookAt.setLatitude(41.26);
lookAt.setLongitude(-100.00);
lookAt.setRange(800000.0);
ge.getView().setAbstractView(lookAt);
}
function failureCB(errorCode) {
alert(errorCode);
}
google.setOnLoadCallback(init);
See HTML code here:
<!DOCTYPE html>
<head>
<script src="http://www.google.com/jsapi"></script>
</head>
<style>
body {
margin:20px;
height:100%;
width:98%;
}
#map3d {
width:75%;
float:right;
}
</style>
<body>
<div id="map3d"></div>
</body>
</html>
The you can use wkhtml2pdf (code.google.com/p/wkhtmltopdf/) function wkhtmltoimage, or PhantomJs (github.com/ariya/phantomjs/wiki/Screen-Capture) to get an image version.
Hope it helps!
Cheers,
Mihai

Resources