Hi I m trying to draw an image on canvas using threejs
Code:
<html lang="en">
<head>
<title>three.js webgl - materials - canvas texture</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
<style>
#drawing-canvas {
position: absolute;
background-color: #000000;
top: 0px;
right: 0px;
z-index: 3000;
cursor: crosshair;
}
</style>
</head>
<body>
<img id="endPoint" width="15" height="15" src="endpoint.png" alt="The End Point">
<div id="info">
three.js - webgl - canvas as a texture
<div>click and draw in the white box</div>
</div>
<canvas id="drawing-canvas" height="100" width="100"></canvas>
<script type="module">
import * as THREE from '../build/three.module.js';
var camera, scene, renderer, mesh, material;
var drawStartPos = new THREE.Vector2();
init();
setupCanvasDrawing();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 500;
scene = new THREE.Scene();
material = new THREE.MeshBasicMaterial();
mesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 200, 200, 200 ), 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 );
window.addEventListener( 'resize', onWindowResize, false );
}
// Sets up the drawing canvas and adds it as the material map
function setupCanvasDrawing() {
var selectedPoints = 0;
// get canvas and context
var drawingCanvas = document.getElementById( 'drawing-canvas' );
var img = document.getElementById('endPoint');
var drawingContext = drawingCanvas.getContext( '2d' );
var imgmap = new THREE.TextureLoader().load( "endpoint.png" );
var imgmaterial = new THREE.SpriteMaterial( { map: imgmap, color: 0x0000ff } );
// draw white background
drawingContext.fillStyle = '#FFFFFF';
drawingContext.fillRect( 0, 0, 128, 128 );
// set canvas as material.map (this could be done to any map, bump, displacement etc.)
material.map = new THREE.CanvasTexture( drawingCanvas );
// set the variable to keep track of when to draw
var paint = false;
// add canvas event listeners
drawingCanvas.addEventListener( 'mousedown', function ( e ) {
selectedPoints++;
if ( selectedPoints == 1 ) {
drawStartPos.set( e.offsetX, e.offsetY );
//drawingContext.drawImage(img, 5, 5);
var imgsprite = new THREE.Sprite( imgmaterial );
scene.add( imgsprite );
//imgsprite.scale.set(5,5,1);
imgmap.needsUpdate = true;
}
if ( selectedPoints == 2 ) {
//drawingContext.drawImage(img, 5, 5);
selectedPoints = 0;
draw(drawingContext, e.offsetX, e.offsetY);
//drawingContext.drawImage(img, 5, 5);
var imgsprite = new THREE.Sprite( imgmaterial );
scene.add( imgsprite );
//imgsprite.scale.set(5,5,1);
imgmap.needsUpdate = true;
}
//console.log("Paint in mousedown : " + paint)
} );
}
function draw( drawContext, x, y ) {
drawContext.beginPath();
drawContext.moveTo( drawStartPos.x, drawStartPos.y );
drawContext.strokeStyle = '#0000FF';
drawContext.lineTo( x, y );
drawContext.closePath();
drawContext.fill();
drawContext.stroke();
// reset drawing start position to current position.
drawStartPos.set( x, y );
// need to flag the map as needing updating.
material.map.needsUpdate = true;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render( scene, camera );
}
</script>
</body>
</html>
This is modified from the existing example of drawing on canvas in threejs as shown here
Problem is I was able to draw lines between two points that are selected by a mouse click but cannot see the image. I don't know if I m doing right by adding the image to the scene. Please advise.
I want a user to be able to upload an image from his own computer, which should be set as a background image for Three.js. This image should be a static background. Is it possible to save the image just in a variable?
My current code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>See your new car where you want it</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
</head>
<body>
<input type="file" onchange="selectBackground()" multiple accept='image/*'><br>
<script src="js/three.js"></script>
<script src="js/OrbitControls.js"></script>
<script>
var scene;
var camera;
var renderer;
function selectBackground()
{
console.log("getting image");
var newBackground;
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
newBackground = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
setBackground(newBackground);
}
function setBackground(image)
{
console.log("setting background");
//init of three.js
//init Three.js
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 400, 200, 0 );
//set background color to white
//scene.background = new THREE.Color(0xffffff);
//set background
scene.backgroundImage = new THREE.CanvasTexture(image);
renderer = new THREE.WebGLRenderer();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
document.body.appendChild( renderer.domElement );
controls = new THREE.OrbitControls( camera, renderer.domElement );
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 2;
animate();
}
var animate = function () {
requestAnimationFrame( animate );
renderer.render( scene, camera );
};
</script>
</body>
</html>
It would be awesome if you would be able to help me with this.
You'll want to run this full page, otherwise it's hard to see the result....
var scene;
var camera;
var renderer;
function selectBackground() {
//console.log("getting image");
var newBackground;
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function() {
//console.log("Loaded.");
newBackground = reader.result;
var img = document.createElement('img');
//preview.src =
img.src = reader.result;
var tex = new THREE.Texture(img);
tex.needsUpdate = true;
setBackground(tex);
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
previewFile()
}
function setBackground(tex) {
//console.log("setting background");
//init of three.js
//init Three.js
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(10, 10, 10);
//set background color to white
//scene.background = new THREE.Color(0xffffff);
//set background
scene.background = tex; //new THREE.CanvasTexture(image);
renderer = new THREE.WebGLRenderer();
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(800, 600); //window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 2;
animate();
}
var animate = function() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>See your new car where you want it</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input type="file" onchange="selectBackground()" multiple accept='image/*'><br>
<!--img id="preview">preview</img-->
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
</body>
</html>
I had difficulty exporting more than one texture using Blender's Three.js add-on, so had planned to work around it be separating the parts into separate meshes, but then came across the unexpected problem of the code not working when I created the meshes outside of the load() function. I've supplied an example below using a single model with a single mesh. The following works fine:
<!DOCTYPE html>
<html lang="en">
<head>
<title>working</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="js/build/three.min.js"></script>
<script src="js/loaders/ColladaLoader.js"></script>
<script src="js/Detector.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container;
var camera, scene, renderer, objects;
var scaleAdj = 100;
init();
animate();
function init()
{
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
camera.position.set( 0, 500, 0 );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xcce0ff, 10, 10000 );
var loader = new THREE.JSONLoader();
loader.load( 'cube.json', function ( geometry, materials )
{
var faceMaterial = new THREE.MultiMaterial( materials );
for ( var i = 0; i < 250; i ++ )
{
var x = ( ( i % 27 ) - 13.5 ) * (5 * scaleAdj) + THREE.Math.randFloatSpread( 300 * scaleAdj);
var z = ( Math.floor( i / 27 ) - 13.5 ) * (5 * scaleAdj) + THREE.Math.randFloatSpread( 300 * scaleAdj);
mesh = new THREE.Mesh( geometry, faceMaterial );
var s = THREE.Math.randFloat( 0.5, 2 ) * scaleAdj;
mesh.scale.set( s, s, s );
mesh.position.set( x, scaleAdj, z );
mesh.rotation.y = THREE.Math.randFloat( -0.25, 0.25 );
mesh.matrixAutoUpdate = false;
mesh.updateMatrix();
scene.add( mesh );
}
} );
scene.add( new THREE.AmbientLight( 0xffffff ) );
// ground
var textureLoader = new THREE.TextureLoader();
var groundTexture = textureLoader.load( "texture.jpg" );
groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
groundTexture.repeat.set( 40, 40 );
groundTexture.anisotropy = 16;
var groundMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, map: groundTexture } );
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 20000, 20000 ), groundMaterial );
mesh.position.y = 0;
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
// Renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( scene.fog.color );
container.appendChild( renderer.domElement );
// Events
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize( event ) {
renderer.setSize( window.innerWidth, window.innerHeight );
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
</html>
But this doesn't (I've annotated which sections contain the differences):
<!DOCTYPE html>
<html lang="en">
<head>
<title>not working</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="js/build/three.min.js"></script>
<script src="js/loaders/ColladaLoader.js"></script>
<script src="js/Detector.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
//--------------- difference number 1
var obj_geometry;
var obj_material;
//-----------------------------------
var container;
var camera, scene, renderer, objects;
var scaleAdj = 100;
init();
animate();
function init()
{
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
camera.position.set( 0, 500, 0 );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xcce0ff, 10, 10000 );
//-------------------difference number 2--------------------
var loader = new THREE.JSONLoader();
loader.load( 'cube.json', function ( geometry, material )
{
obj_geometry = geometry;
obj_material = material;
});
var faceMaterial = new THREE.MultiMaterial( obj_material);
for ( var i = 0; i < 250; i ++ )
{
var x = ( ( i % 27 ) - 13.5 ) * (5 * scaleAdj) + THREE.Math.randFloatSpread( 300 * scaleAdj);
var z = ( Math.floor( i / 27 ) - 13.5 ) * (5 * scaleAdj) + THREE.Math.randFloatSpread( 300 * scaleAdj);
mesh = new THREE.Mesh( obj_geometry, faceMaterial);
var s = THREE.Math.randFloat( 0.5, 2 ) * scaleAdj;
mesh.scale.set( s, s, s );
mesh.position.set( x, 0, z );
mesh.rotation.y = THREE.Math.randFloat( -0.25, 0.25 );
mesh.matrixAutoUpdate = false;
mesh.updateMatrix();
scene.add( mesh );
}
//--------------------------------------
scene.add( new THREE.AmbientLight( 0xffffff ) );
// ground
var textureLoader = new THREE.TextureLoader();
var groundTexture = textureLoader.load( "texture.jpg" );
groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
groundTexture.repeat.set( 40, 40 );
groundTexture.anisotropy = 16;
var groundMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, map: groundTexture } );
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 20000, 20000 ), groundMaterial );
mesh.position.y = 0;
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
// Renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( scene.fog.color );
container.appendChild( renderer.domElement );
// Events
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize( event ) {
renderer.setSize( window.innerWidth, window.innerHeight );
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
</html>
Here is a copy of the contents of the cube.json file:
{
"uvs":[[0,0,1,0,1,1,0,1]],
"faces":[43,0,1,2,3,0,0,1,2,3,0,1,2,3,43,4,7,6,5,0,0,1,2,3,4,5,6,7,43,0,4,5,1,0,0,1,2,3,0,4,7,1,43,1,5,6,2,0,0,1,2,3,1,7,6,2,43,2,6,7,3,0,0,1,2,3,2,6,5,3,43,4,0,3,7,0,0,1,2,3,4,0,3,5],
"normals":[0.577349,-0.577349,-0.577349,0.577349,-0.577349,0.577349,-0.577349,-0.577349,0.577349,-0.577349,-0.577349,-0.577349,0.577349,0.577349,-0.577349,-0.577349,0.577349,-0.577349,-0.577349,0.577349,0.577349,0.577349,0.577349,0.577349],
"metadata":{
"generator":"io_three",
"type":"Geometry",
"normals":8,
"vertices":8,
"uvs":1,
"version":3,
"materials":1,
"faces":6
},
"vertices":[1,-1,-1,1,-1,1,-1,-1,1,-1,-1,-1,1,1,-1,0.999999,1,1,-1,1,1,-1,1,-1],
"materials":[{
"DbgName":"Material",
"colorSpecular":[0.5,0.5,0.5],
"DbgIndex":0,
"mapDiffuseWrap":["RepeatWrapping","RepeatWrapping"],
"mapDiffuse":"texture.jpg",
"shading":"phong",
"depthTest":true,
"opacity":1,
"transparent":false,
"colorDiffuse":[0.64,0.64,0.64],
"mapDiffuseAnisotropy":1,
"blending":"NormalBlending",
"depthWrite":true,
"visible":true,
"specularCoef":50,
"mapDiffuseRepeat":[1,1],
"colorEmissive":[0,0,0],
"wireframe":false,
"DbgColor":15658734
}],
"name":"CubeGeometry"
}
And here is an attached texture which could be used.
It might just be a trivial problem for some of the posters on here, and if so, thanks in advance for just letting me know what it is. If not, then the answer could be useful to a lot more people, and thanks for any help you can give on it.
You cant do this, asynchronously:
var obj_geometry; // === undefined
var myMesh = new THREE.Mesh( obj_geometry ); //because undefined, same as calling new THREE.Mesh();
obj_geometry = geometry;//does nothing, mesh has no idea about this happening
obj_material = material;
When you construct a mesh, you've given it undefined for geometry, so i think it just calls new Geometry() inside the constructor. This mesh has been created with a unique isntance of empty Geometry and has nothing to do with your obj_geometry.
The solution here is to do:
var obj_geometry = new THREE.Geometry();
var myMesh = new THREE.Mesh( obj_geometry ); //holds a reference to an empty "proxy"
then onLoad
loader.load( 'url' , function( geom ) {
obj_geometry.merge(geom); //"FILL PREVIOUSLY CREATED GEOMETRY WITH DATA"
obj_geometry.vertsNeedUpdate = true; // there's a few flags like this you need to turn on
}
OR
var myMesh = new THREE.Mesh();
loader.load( 'url', function( geom ) {
myMesh.geometry = geom; //"PUT THE JUST CREATED GEOMETRY IN THE RIGHT PLACE"
//myOtherMesh.geometry = geom; //if you have more places where this needs to end up
//myThirdMesh.geometry = geom; //gets very cumbersome
}
Both are pretty cumbersome and not very intuitive :( i really dislike this part of three.js.
Thanks to help from pailhead, pointing out the asynchronous issue I made the following modification to the code and found that it worked. Surprisingly the count that I added doesn't seem to raise above 0, but I am assuming that it was because it was quite a close run thing.
<!DOCTYPE html>
<html lang="en">
<head>
<title>asynchronous working</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="build/three.min.js"></script>
<script>
//--------------- difference number 1
var obj_geometry;
var obj_material;
var loaded = false;
//-----------------------------------
var container;
var camera, scene, renderer, objects;
var scaleAdj = 100;
init();
animate();
function init()
{
container = document.createElement( 'div' );
document.body.appendChild( container );
//-----an info display
info = document.createElement( 'div' );
info.id = "info";
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
container.appendChild(info);
//-----------------
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
camera.position.set( 0, 500, 0 );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xcce0ff, 10, 10000 );
//-------------------difference number 2--------------------
var loader = new THREE.JSONLoader();
loader.load( 'cube.json', function ( geometry, material )
{
obj_geometry = geometry;
obj_material = material;
loaded = true;
});
var notLoadedCount = 0;
var processor = setInterval(function()
{
if(!loaded)
{
notLoadedCount++;
}
else
{
var faceMaterial = new THREE.MultiMaterial( obj_material);
for ( var i = 0; i < 250; i ++ )
{
var x = ( ( i % 27 ) - 13.5 ) * (5 * scaleAdj) + THREE.Math.randFloatSpread( 300 * scaleAdj);
var z = ( Math.floor( i / 27 ) - 13.5 ) * (5 * scaleAdj) + THREE.Math.randFloatSpread( 300 * scaleAdj);
mesh = new THREE.Mesh( obj_geometry, faceMaterial);
var s = THREE.Math.randFloat( 0.5, 2 ) * scaleAdj;
mesh.scale.set( s, s, s );
mesh.position.set( x, 0, z );
mesh.rotation.y = THREE.Math.randFloat( -0.25, 0.25 );
mesh.matrixAutoUpdate = false;
mesh.updateMatrix();
scene.add( mesh );
info.innerHTML= '*not loaded count = ' + notLoadedCount;
}
clearInterval(processor);
}
}, 100);
//--------------------------------------
scene.add( new THREE.AmbientLight( 0xffffff ) );
// ground
var textureLoader = new THREE.TextureLoader();
var groundTexture = textureLoader.load( "texture.jpg" );
groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
groundTexture.repeat.set( 40, 40 );
groundTexture.anisotropy = 16;
var groundMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, map: groundTexture } );
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 20000, 20000 ), groundMaterial );
mesh.position.y = 0;
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
// Renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( scene.fog.color );
container.appendChild( renderer.domElement );
// Events
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize( event ) {
renderer.setSize( window.innerWidth, window.innerHeight );
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
</html>
Thanks for the help with this, hopefully it helps others too. If there are any problems with this resolution that anybody notices, please let me know. Thanks.
I've been playing around with this ThreeJS library for a couple of weeks now, and using inspiration from others, I've made a canvas that displays an external .stl-file.
My only problem is I can't seem to apply any transformations to it. I can move the camera around just fine, but I can't get even the most simple transformations to work. I'm not best with JavaScript, so I might have missed some essential parts.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - STL</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/loaders/STLLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="dat.gui.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container;
var rotationSpeed;
var camera, cameraTarget, scene, renderer;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 15 );
camera.position.set( -3, 1, 3 );
cameraTarget = new THREE.Vector3( 0, 0, 0 );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0x72645b, 2, 15 );
// Ground
var plane = new THREE.Mesh( new THREE.PlaneGeometry( 40, 40 ), new THREE.MeshPhongMaterial( { ambient: 0x999999, color: 0x999999, specular: 0x101010 } ) );
plane.rotation.x = -Math.PI/2;
plane.position.y = -0.5;
scene.add( plane );
plane.receiveShadow = true;
// ASCII file
var loader = new THREE.STLLoader();
loader.addEventListener( 'load', function ( event ) {
var geometry = event.content;
var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200 } );
var model = new THREE.Mesh( geometry, material );
model.position.set( 0, 0.05, 0 );
model.rotation.set( Math.PI / 2.0, - Math.PI / 1.5, 0 );
model.scale.set( 0.01, 0.01, 0.01 );
model.castShadow = true;
model.receiveShadow = true;
scene.add( model );
} );
loader.load( './models/stl/ascii/cover.stl' );
// Lights
scene.add( new THREE.AmbientLight( 0x777777 ) );
addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
addShadowedLight( 0.5, 1, -1, 0xffaa00, 1 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( scene.fog.color, 1 );
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMapEnabled = true;
renderer.shadowMapCullFace = THREE.CullFaceBack;
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
function addShadowedLight( x, y, z, color, intensity ) {
var directionalLight = new THREE.DirectionalLight( color, intensity );
directionalLight.position.set( x, y, z )
scene.add( directionalLight );
directionalLight.castShadow = true;
// directionalLight.shadowCameraVisible = true;
var d = 1;
directionalLight.shadowCameraLeft = -d;
directionalLight.shadowCameraRight = d;
directionalLight.shadowCameraTop = d;
directionalLight.shadowCameraBottom = -d;
directionalLight.shadowCameraNear = 1;
directionalLight.shadowCameraFar = 4;
directionalLight.shadowMapWidth = 1024;
directionalLight.shadowMapHeight = 1024;
directionalLight.shadowBias = -0.005;
directionalLight.shadowDarkness = 0.15;
}
/* var controls = new function()
{
this.rotationSpeed = 0.2;
}
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed',0,1);
*/
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var timer = Date.now() * 0.0005;
camera.lookAt( cameraTarget );
//THIS LINE DOESN'T WORK
//model.position.x = Math.cos( timer );
//model.position.z = Math.sin( timer );
renderer.render( scene, camera );
}
</script>
</body>
</html>
The last lines before the render() function just gives me a black, blank page.
Even things like model.position.x += 0.02; kills it
I could find the mistake here , but sorry some how not able to port your code to JSFIDDLE
Here is the problem I found,
model variable is not declared in the global scope. It is initialized locally in the init() function and you are trying the manipulate that variable with in the render function, where it does not have any scope.
So the solution is Just declare the variable model before calling the init() function just like other variables that you are declaring there by adding this below line.
var model;