The editor project I am making should allow me to Import a cdn library and use it to write code . So to show my problem , enter https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js in the import cdn input and click import . Then enter this in the code section :
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
Click the run button at the top . You should get a tiny three js window at the bottom. My first question is , why is the text undefined coming above the render ? And two , if you change the code in the input to :
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
It adds another render to the div . Why ? especially when I have used the .html method to replace the contents of the div . My complete code is visible here
By inspecting the Javascript console, it's clear that the renderer is not added to #body2 but rather to the document.body.
This line:
document.body.appendChild( renderer.domElement );
appends the renderer to the body element.
The undefined is because of String( eval( $("#editor #editor-textarea").val() ));
The text content in eval must return something.
https://www.w3schools.com/jsref/jsref_eval.asp
In this case, the return value of $("#editor #editor-textarea").val() is undefined. Hence eval(undefined) is undefined and String(undefined) is "undefined"
Related
I have a custom GLTF model I have loaded into my scene, however I'm having trouble positioning and animating the mesh. Currently, I have the mesh's position set to 0,0,0 and have moved the camera position so that the mesh is on the screen when it is loaded, otherwise you would have to pan around to find it. I just changed the camera position slowly until I could finally see it without having to pan the camera. I'm trying to set the default rotation of the mesh, however whenever I change any of the values, the mesh moves really far away and I would have to redo the camera position so that you can see it again. Why does this happen, and is there a way so that once I have the default rotation and position set I can create an animation that just rotates the hand's z-axis in place without the position changing?
Here's my current code:
import * as THREE from './three.js-master/build/three.module.js'
import { OrbitControls } from './three.js-master/examples/jsm/controls/OrbitControls.js';
import {GLTFLoader} from './three.js-master/examples/jsm/loaders/GLTFLoader.js';
const scene = new THREE.Scene();
const loader = new GLTFLoader();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth,window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
})
const controls = new OrbitControls( camera, renderer.domElement );
controls.enablePan = false;
controls.enableZoom = false;
controls.update();
// const geometry = new THREE.TorusGeometry( 6.46, 1.5, 20, 100 );
// const material = new THREE.MeshBasicMaterial( { color: 0xf542d7 } );
// const torus = new THREE.Mesh( geometry, material );
// scene.add( torus );
loader.load(
// resource URL
'./models/hand/hand.gltf',
// called when the resource is loaded
function ( gltf ) {
scene.add( gltf.scene );
gltf.animations; // Array<THREE.AnimationClip>
gltf.scene; // THREE.Group
gltf.scenes; // Array<THREE.Group>
gltf.cameras; // Array<THREE.Camera>
gltf.asset; // Object
gltf.scene.children[0].position.set(0,0,0);
},
// called while loading is progressing
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened' );
}
);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(0,0,100)
scene.add( directionalLight );
camera.position.set(-300,570,0);
function animate() {
// torus.rotation.y += 0.01;
gltf.scene.children[0].rotation.z += 0.01;
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
animate();`
I have tried to set the rotation axis separately as well as trying to set an outside variable equal to the gltf.scene.children[0] to rotate it in the animate function.
I cannot center three js object into DIV
Here is my code:
import * as THREE from 'https://cdn.skypack.dev/pin/three#v0.128.0-iDyvDZdRCoyR9DXa2rWg/mode=imports,min/optimized/three.js';
const container = document.getElementById("canvas");
// const selected = document.querySelector("#canvas");
// document.body.appendChild(container);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( container.offsetWidth, container.offsetWidth );
// renderer.setSize( item.clientWidth, item.clientHeight );
container.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
And that's how the problem looks:
Object just going outside the DIV:
I dont know why it happens. I'm trying to fix this a couple of days and try a lot of ways and it still does not work. Probably I don't understand something and need your help...
I guess i solved the problem. I just delete padding of the #canvas in css and its now work as expected.
Im having troubles with Orbitcontrols. I have my threee js model and i want it to autorotate when the page is loaded for the first time but for some reason it does not work properly. The 3d model stand still as if the command line was not considered.
Here is the code where i initialize the function:
the init() function where i declare my model and add them to the scene:
controls.autoRotate=true
controls.addEventListener('change', render);
render();
the render function:
function render() {
renderer.render(scene, camera);
}
Please note that i can move my model as i wish in my page but the automatic rotation does not seem to be triggered.
Using OrbitControls.autoRotate only works if you call controls.update() in your animation loop. You can't use automatic rotation in combination with on-demand rendering (meaning by utilizing the change event listener of the controls).
let camera, scene, renderer, controls;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 1;
scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
const material = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.autoRotate = true;
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.124/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.124/examples/js/controls/OrbitControls.js"></script>
I'm trying to work out camera navigation functionality in threejs, using THREE.OrbitControls. Even though I'm following a guide, I just can't seem to get it working.
The link to my fiddle code is: https://jsfiddle.net/Matty1/uc671jbL/18/
It's on line 18/19 of the javascript:
const controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.update();
Any advice would be appreciated.
You have included OrbitControls from a relative path in your fiddle. Try it like so:
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x19d7f8);
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set(0,0,5);
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
window.addEventListener('resize', function(){
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width/height;
camera.updateProjectionMatrix;
} )
const controls = new THREE.OrbitControls( camera, renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
animate();
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.124/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.124/examples/js/controls/OrbitControls.js"></script>
I want to to enable dat-gui controls for the threejs camera in the basic threejs example on this page:
https://github.com/mrdoob/three.js/
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1000;
scene = new THREE.Scene();
geometry = new THREE.CubeGeometry( 200, 200, 200 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
// note: three.js includes requestAnimationFrame shim
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
I've tried the following code:
var params = {
z: 100
}
var gui = new dat.GUI();
gui.add(params, 'z', -500,500).step(5).onChange(function(value){
changeCameraZ(value);
});
function changeCameraZ(value){
camera.position.z = value;
}
which works, but it means that I have to write a new function:
changeBlah();
for each three.js variable I wish to change from the GUI. Is there a better, cleaner way of achieving this?
You could also make use of how DAT.gui makes use of references.
gui.add( camera.position , 'z', -500, 500 ).step(5)
and an example
http://jsfiddle.net/2WKqL/2/
This one-liner should work.
gui.add( params, 'z', -500, 500 ).step(5).onChange( function( value ){ camera.position.z = value; } );