I try to do a 3D animation with Three.js controls. During the execution of my code in Firefox, a have this error :
EDIT
SyntaxError: import declarations may only appear at top level of a module
And here is my code, simplified :
<!DOCTYPE html>
<head>
<title>Three.js Test</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100%;};
</style>
</head>
<body>
<script src="js/three.js"></script>
<script src="js/OrbitControls.js"></script>
<script type="module">
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//keep the scene in center of the page
window.addEventListener('resize', function() {
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width,height);
//prevent distortion
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
controls = new THREE.OrbitControls(camera, renderer.domElement);
// create the shape
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0xFF0080 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
function animate()
{
requestAnimationFrame( animate );
/*cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
cube.rotation.z += 0.01;*/
renderer.render( scene, camera );
}
animate();
</script>
</body>
</html>
I don't understand where the error came from and I don't know how to fix it.
I now run my code on a wamp server.
Thanks for your help !
import * as THREE from './jsthree.module.js';
It seems there is a typo. It should be ./js/three.module.js.
In any event, ensure to run your code on a local web server in order to avoid any security issues. More information about this topic in the following guide:
https://threejs.org/docs/index.html#manual/en/introduction/How-to-run-things-locally
Related
I'm trying to upload a 3D model to my scene in three.js however I have trouble doing this.
I decided to recreate an example to practice which is shown below but I still get error and it doesn't work.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Website first attempt</title>
<script src="js/three.min.js"></script>
<script type = "module"src="js/OrbitControls.js"></script>
<script type = "module" src="js/GLTFLoader.js"></script>
<style>
body { margin: 0;}
canvas { display: block; }
</style>
</head>
<body>
<div class = "wave"></div>
<script type = "module">
var scene, camera, renderer, controls;
var hlight,directionalLight, light, light2, light3, light4;
function init () {
//scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xdddddd );
//camera
camera = new THREE.PerspectiveCamera(40,window.innerWidth/window.innerHeight,1,5000);
camera.rotation.y = 45/180*Math.PI;
camera.position.x = 800;
camera.position.y = 100;
camera.position.z = 1000;
//render
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
hlight = new THREE.AmbientLight (0x404040,100);
scene.add(hlight);
directionalLight = new THREE.DirectionalLight(0xffffff,100);
directionalLight.position.set(0,1,0);
directionalLight.castShadow = true;
scene.add(directionalLight);
light = new THREE.PointLight(0xc4c4c4,10);
light.position.set(0,300,500);
scene.add(light);
light2 = new THREE.PointLight(0xc4c4c4,10);
light2.position.set(500,100,0);
scene.add(light2);
light3 = new THREE.PointLight(0xc4c4c4,10);
light3.position.set(0,100,-500);
scene.add(light3);
light4 = new THREE.PointLight(0xc4c4c4,10);
light4.position.set(-500,300,500);
scene.add(light4);
var loader = new THREE.GLTFLoader();
loader.load('scene.gltf', function(gltf){
car = gltf.scene.children[0];
car.scale.set(0.5,0.5,0.5);
scene.add(gltf.scene);
animate();
});
}
function onWindowResize () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
window.addEventListener('resize', onWindowResize, false);
function animate () {
requestAnimationFrame(animate);
controls.update();
render();
}
function render() {
renderer.render( scene, camera );
}
init ();
animate();
</script>
</body>
</html>
Comes with an error:
GET http://127.0.0.1:5500/build/three.module.js net::ERR_ABORTED 404
(Not Found) index4.html:78 Uncaught TypeError: THREE.GLTFLoader is not
a constructor
at init (index4.html:78)
at index4.html:122
I think easier to stick to the example's code style and organize your imports like so:
<script type = "module">
import * as THREE from '../build/three.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
var scene, camera, renderer, controls;
Meaning three.module.js, OrbitControls and GLTFLoader are ES6 modules. In this case, you can create an instance of GLTFLoader without the THREE namespace. Same for OrbitControls.
Notice that it's no good approach to mix ES6 modules with non-ES6 modules. If you do so, you will be inevitably faced with issues which are really hard to track down. E.g. libraries like three.js get included twice.
I got this code from webgl I have used it same as they mentioned in their tutorial but i cannot get result on my browser screen only i can see is just black background nothing else. i have used three.js library to create 3d model of cube.
<pre>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
canvas { width: 100%; height: 100% }
</style>
<title>Pryamid</title>
</head>
<body>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var cubegeometry = new THREE.CubeGeometry(1,1,1);
var cubematerial = new THREE.MeshBasicMaterial({wireframe: true, color: 0x000000});
var cube = new THREE.Mesh(cubegeometry, cubematerial);
scene.add(cube);
camera.position.z = 5;
var render = function () {
requestAnimationFrame(render);
cube.rotation.y += 0.01;
cube.rotation.x += 0.01;
cube.rotation.z += 0.01;
renderer.render(scene, camera);
};
// Calling the render function
window.onload = function() {
render();
};
</script>
</body>
</html>
Is this your full code? I think it would be helpful if you posted the full HTML context of what you're trying to achieve.
However, what I see at first blink, is that you either don't add the rendering target to your HTML page, or you don't use the canvas you have in your HTML to render to.
The easiest way to get your cube displayed, is by adding the rendering canvas to your page's DOM, with:
document.body.appendChild( renderer.domElement );
For some reason with this code it will not call 'createScene();' in index.html. I'm probably overlooking something very simple as I'm new to JS but I haven't been able to find anything.
index.html
<html>
<head>
<title>Pallidity</title>
<script type = "text/javascript" src="Javascript/scene.js"></script>
<style type ="text/css">
BODY
{
Margin: 0;
}
canvas
{
width: 100%;
height:100%;
}
</style>
</head>
<body>
<script type="text/javascript">
createScene();
</script>
</body>
scene.js:
function createScene(){
<script src="Libraries/three.min.js"></script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//Bare minmum to render
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x045f00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
}
You have an html element (a script tag) as the first line of you createScene function. This is not valid JavaScript, therefore that function essentially does not exist. That's why it is not defined.
You probably want this line in your HTML file right before your scene.js script tag.
I am trying to attempt to learn Three.js from their getting started guide: http://threejs.org/docs/index.html#Manual/Introduction/Creating_a_scene and I have the code as exactly from the site. I am using the latest code from their site, as for the library. The error in the console is as follows:
Uncaught TypeError: Object #<Object> has no method 'mergeVertices'
I am not really too sure on what the issue is
Here is the code that is from the site that I am using:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>First Three JS App</title>
<style>
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
// To be able to view anything with Three.js we need a scene, a camera, and a renderer
// -> To render the scene with the camera
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth / window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry = THREE.BoxGeometry(10, 10, 10 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 });
var cube = new THREE.Mesh( geometry, material);
scene.add( cube );
camera.position.z = 5;
var render = function render() {
requestAnimationFrame( render )
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render( scene, camera );
};
render();
</script>
</body>
</html>
From what #WestLangley suggested, I needed to review my code. I was missing a new in geometry declaration, and my renderer.setSize call needed 2 params instead of 1 (I was using a ratio) and the final var render = function.... I needed to take out the second render
Sometimes it is good to have a second pair of eyes.. Thanks again #WestLangley
i asked yesterday about how to draw 3D objects in the browser, be able to manipulate them with the mouse and be sure that it works in every browser. Now i am using three.js and im quite happy because it actually works.
I was able to understand the basic tutorial, draw my first scene and rotate the first cube etc.
Now i want to be able to rotate the complete scene with the mouse, googled and found this link. Works fine in the example and i tried to copy the example. Current code looks like this:
<html>
<head>
<title>My first Three.js app</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="three.min.js"></script>
<script src="TrackballControls.js"></script>
<script type="text/javascript">
// Variables
var scene, camera, controls, renderer;
var geometry, material, cube;
init();
animate();
render();
function init() {
// Scene, camera
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 500, window.innerWidth / window.innerHeight, 0.1, 1000 );
// Mouse controls
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener('change',test,false);
// Renderer
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// Basic cube to show
geometry = new THREE.CubeGeometry(10,10,10);
material = new THREE.MeshBasicMaterial({color:0x00ff00});
cube = new THREE.Mesh(geometry);
scene.add(cube);
camera.position.z = 10;
}
function test() {
alert("hi");
render();
}
function animate() {
requestAnimationFrame(render);
controls.update();
}
function render() {
renderer.render(scene, camera);
//cube.rotation.x += 0.1;
//cube.rotation.y += 0.1;
}
</script>
</body>
But it doesn't work. The testoutput "hi" only appears once. It should appear quite often when using the mouse. What i tried to accomplish is that controls.addEventListener('change',test,false); looks if anything with the mouse changes (position, keydown etc.) and then calls a new renderframe. In the example (Example) it somehow does what i want it to do.
What am i doing wrong here? I just want to be able to rotate the camera with mousedragging. And yes i am totally new to this. Just read about it for 2 hours now.
Thanks in advance.