Grabbing coordinates from render canvas instead of entire window - javascript

I'm experiencing a small problem with an editor I'm building. it's a terrain editor, with toolbars on the left and top, with a canvas on the bottom right. There is a beacon named 'helperHandle' in the canvas which will demonstrate which vector you are currently hovering over. however, the beacon doesn't align properly with the mouse, it seems to be using the entire window as an offset, instead of just the rendering canvas. as you can see from the image below. I've included my code below the image.
The javascript >>
$( document ).ready(function() {
var terrainMesh;
var helperHandle;
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var cameraholder;
function main() {
const canvas = document.querySelector('#terrainRender');
const renderer = new THREE.WebGLRenderer({canvas, alpha: true});
var cubes = [];
const fov = 40;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 1000;
cameraholder = new THREE.Object3D();
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0,10,20);
camera.lookAt( 0, 0, 0 );
camera.zoom = 0.5;
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0x555555 );
scene.add(cameraholder);
var size = 10;
var divisions = 10;
var gridHelper = new THREE.GridHelper( size, divisions );
scene.add( gridHelper );
var axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
const color = 0xFFFFFF;
const intensity = 0.1;
light = new THREE.DirectionalLight(color, intensity);
light.position.set(1, 30, 10);
light.target.position.set( 0, 0, 0 );
light.castShadow = true;
var lightHelper = new THREE.DirectionalLightHelper( light, 5 );
scene.add( lightHelper );
const controls = new THREE.OrbitControls(camera, canvas);
controls.target.set(0, 0, 0);
controls.update();
scene.add( light );
var geometry = new THREE.PlaneBufferGeometry(60, 60, 9, 9);
var material = new THREE.MeshBasicMaterial(
{color: 0x666666,
side: THREE.DoubleSide
});
rotateObject(geometry, -90, 0, 0);
geometry.computeFaceNormals(); // needed for helper
var helperHandlegeometry = new THREE.ConeBufferGeometry( 1, 3, 3 );
helperHandlegeometry.rotateX( Math.PI / 2 );
helperHandle = new THREE.Mesh( helperHandlegeometry, new THREE.MeshNormalMaterial() );
scene.add( helperHandle );
terrainMesh = new THREE.Mesh( geometry, material );
scene.add( terrainMesh );
var wireframe = new THREE.WireframeGeometry( geometry );
var line = new THREE.LineSegments( wireframe );
line.material.depthTest = false;
line.material.opacity = 0.25;
line.material.transparent = true;
scene.add( line );
function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {
const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
const halfFovY = THREE.MathUtils.degToRad(camera.fov * .5);
const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
const direction = (new THREE.Vector3())
.subVectors(camera.position, boxCenter)
.multiply(new THREE.Vector3(1, 0, 1))
.normalize();
camera.near = boxSize / 100;
camera.far = boxSize * 100;
camera.updateProjectionMatrix();
camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = renderer.domElement.clientWidth;
const height = renderer.domElement.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render(time) {
time *= 0.001;
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = renderer.domElement.clientWidth / renderer.domElement.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function onMouseMove( event ) {
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
terrainMesh.updateMatrixWorld();
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObject( terrainMesh );
if ( intersects.length > 0 ) {
helperHandle.position.set( 0, 0, 0 );
helperHandle.lookAt( intersects[ 0 ].face.normal );
helperHandle.position.copy( intersects[ 0 ].point );
}
$('#coords').html(`X: ${mouse.x.toFixed(2)} <br>Y: ${mouse.y.toFixed(2)}`);
}
window.addEventListener( 'mousemove', onMouseMove, false );
requestAnimationFrame(render);
}
main();
});
The html >>
<div id="main">
<div id="toolBar">
</div>
<div class="editorWindow">
<div id="sideBar"></div>
<canvas id="terrainRender"></canvas>
<div id="coords"></div>
</div>
</div>
The CSS (less) >>
div{
}
body { margin: 0; }
#coords{
position: absolute;
top: 0;
width: 40px;
height: 40px;
background-color: #fff;
}
.titleBar{
height: 30px;
width: 100%;
display: block;
background-color: #e0e0e0;
}
#main{
position: relative;
background-color: #f4f4f4;
display: grid;
height: 99vh;
flex-wrap: wrap;
border: 1px solid #aaa;
padding: 0.2%;
.editorWindow{
flex: 1;
flex-direction: row;
display: flex;
}
#toolBar{
height: 60px;
}
#sideBar{
flex: 1 2 10%;
position: relative;
background-color: #f4f4f4;
border: solid 1px #aaa;
}
#terrainRender {
flex: 12 1 80%;
}
}
#terrain{
display: inline-block;
zoom: 100%;
transform-origin: center;
white-space: nowrap;
font-size: 0px;
transform-style: preserve-3d;
/*transform: rotateZ(0deg) rotateY(0deg) rotateX(45deg);*/
}

Related

Three.js How to fit object to left half side of the screen(width and height)

After clicking the button, I want the whole 3D object(width and height) to fit to left side of the screen and show a div HTML info in the right side of the screen.
How to fit object to left side of the screen? Is it possible to set margin(px)?
var camera, scene, renderer;
var geometry, material, mesh;
var lookDirection = new THREE.Vector3();
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 1;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.mouseButtons = {
LEFT: THREE.MOUSE.RIGHT,
MIDDLE: THREE.MOUSE.MIDDLE,
RIGHT: THREE.MOUSE.LEFT
}
controls.enableZoom = false;
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
controls.update();
TWEEN.update();
}
function fit(){
controls.enabled = false;
var box = new THREE.Box3().setFromObject(mesh);
var boxSize = box.getSize(new THREE.Vector3()).length();
var boxCenter = box.getCenter(new THREE.Vector3());
var halfSizeToFitOnScreen = boxSize * 0.5;
var halfFovY = THREE.Math.degToRad(camera.fov * 0.5);
var distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
// compute a unit vector that points in the direction the camera is now
// in the xz plane from the center of the box
const direction = (new THREE.Vector3())
.subVectors(camera.position, boxCenter)
.multiply(new THREE.Vector3(1, 0, 1))
.normalize();
// tween animation
var from = camera.position;
var to = direction.multiplyScalar(distance).add(boxCenter);
var tween = new TWEEN.Tween(from)
.to(to, 1000)
.easing(TWEEN.Easing.Quadratic.InOut)
.onUpdate(function () {
camera.position.set(this.x, this.y, this.z);
// update the Trackball controls to handle the new size
controls.enabled = true;
controls.target.copy(boxCenter);
controls.update();
})
.start();
}
document.getElementById("btn").addEventListener("click", fit);
body {
margin: 0;
overflow: hidden;
}
button {
position: fixed;
top: 0;
left: 0;
}
<button id="btn">Fit</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://sole.github.io/tween.js/build/tween.min.js"></script>
Thanks!
Sounds like you're really just asking an HTML/JavaScript question
One way would be to use a flex box
function fit(){
const elem = document.querySelector('#panes> .right');
elem.style.display = elem.style.display == 'none' ? '' : 'none';
}
document.getElementById("btn").addEventListener("click", fit);
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 0;
}
canvas {
display: block;
width: 100%;
height: 100%;
}
#panes {
display: flex;
width: 100vw;
height: 100vh;
}
#panes>.left,
#panes>.right {
flex: 1 1 50%;
height: 100%;
}
#panes>.left {
padding: 1em;
text-align: center;
background: red;
}
#panes>.right {
padding: 1em;
background: blue;
color: white;
}
button {
position: fixed;
top: 0;
left: 0;
}
<div id="panes">
<div class="left"> Stuff On Left</div>
<div class="right" style="display: none;">Stuff on right</div>
</div>
<button id="btn">Fit</button>
Then insert the canvas in the left pane and use a better example of how to set the canvas's size
var camera, scene, renderer;
var geometry, material, mesh;
var lookDirection = new THREE.Vector3();
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, 2, 0.01, 10 );
camera.position.z = 1;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
document.querySelector("#panes>.left").appendChild( renderer.domElement );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.mouseButtons = {
LEFT: THREE.MOUSE.RIGHT,
MIDDLE: THREE.MOUSE.MIDDLE,
RIGHT: THREE.MOUSE.LEFT
}
controls.enableZoom = false;
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function animate() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render( scene, camera );
controls.update();
TWEEN.update();
requestAnimationFrame( animate );
}
function fit(){
const elem = document.querySelector('#panes> .right');
elem.style.display = elem.style.display == 'none' ? '' : 'none';
}
document.getElementById("btn").addEventListener("click", fit);
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 0;
}
canvas {
display: block;
width: 100%;
height: 100%;
}
#panes {
display: flex;
width: 100vw;
height: 100vh;
}
#panes>.left,
#panes>.right {
flex: 1 1 50%;
height: 100%;
}
#panes>.right {
padding: 1em;
background: blue;
color: white;
}
button {
position: fixed;
top: 0;
left: 0;
}
<div id="panes">
<div class="left"></div>
<div class="right" style="display: none;">Stuff on right</div>
</div>
<button id="btn">Fit</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://sole.github.io/tween.js/build/tween.min.js"></script>
I hope it's not late to answer this question, but I found something that maybe is what you were looking for. Check Is there ANY way to have the three.js camera lookat being rendered off-center?
camera = new THREE.PerspectiveCamera( for, aspect, near, far );
camera.setViewOffset( fullWidth, fullHeight, widthOffset, heightOffset, viewWidth, viewHeight );
Take widthOffset and heightOffset as parameters to slide de target of your camera to any side.

Vanishing text into with css

I'm trying to make an Intro animation with some text for my personal website.
How can I add a text intro like this: https://codepen.io/nathanlong/pen/MyYqNd
over this css animation: https://codepen.io/gvrban/pen/rzNGpW
I've tried to copy/paste and merge the two pens but it doesn't work
I want the text to appear over the animation
Here is the code to the animation
var camera, scene, renderer;
var texture_placeholder,
isUserInteracting = false,
onMouseDownMouseX = 0,
onMouseDownMouseY = 0,
lon = 90,
onMouseDownLon = 0,
lat = 0,
onMouseDownLat = 0,
phi = 0,
theta = 0,
target = new THREE.Vector3();
init();
animate();
function init() {
var container, mesh;
container = document.getElementById('container');
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100);
scene = new THREE.Scene();
texture_placeholder = document.createElement('canvas');
texture_placeholder.width = 128;
texture_placeholder.height = 128;
var context = texture_placeholder.getContext('2d');
context.fillStyle = 'rgb( 200, 200, 200 )';
context.fillRect(0, 0, texture_placeholder.width, texture_placeholder.height);
var materials = [
loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1037366/space4.jpg'), // right
loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1037366/space2.jpg'), // left
loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1037366/space1.jpg'), // top
loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1037366/space6.jpg'), // bottom
loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1037366/space3.jpg'), // back
loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1037366/space5.jpg') // front
];
mesh = new THREE.Mesh(new THREE.BoxGeometry(300, 300, 300, 7, 7, 7), new THREE.MultiMaterial(materials));
mesh.scale.x = -1;
scene.add(mesh);
for (var i = 0, l = mesh.geometry.vertices.length; i < l; i++) {
var vertex = mesh.geometry.vertices[i];
vertex.normalize();
vertex.multiplyScalar(550);
}
renderer = new THREE.CanvasRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener('mousedown', onDocumentMouseDown, false);
document.addEventListener('mousemove', onDocumentMouseMove, false);
document.addEventListener('mouseup', onDocumentMouseUp, false);
//document.addEventListener( 'wheel', onDocumentMouseWheel, false );
document.addEventListener('touchstart', onDocumentTouchStart, false);
document.addEventListener('touchmove', onDocumentTouchMove, false);
//
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function loadTexture(path) {
var texture = new THREE.Texture(texture_placeholder);
var material = new THREE.MeshBasicMaterial({
map: texture,
overdraw: 0.5
});
var image = new Image();
image.onload = function() {
texture.image = this;
texture.needsUpdate = true;
};
image.src = path;
return material;
}
function onDocumentMouseDown(event) {
event.preventDefault();
isUserInteracting = true;
onPointerDownPointerX = event.clientX;
onPointerDownPointerY = event.clientY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
function onDocumentMouseMove(event) {
if (isUserInteracting === true) {
lon = (onPointerDownPointerX - event.clientX) * 0.1 + onPointerDownLon;
lat = (event.clientY - onPointerDownPointerY) * 0.1 + onPointerDownLat;
}
}
function onDocumentMouseUp(event) {
isUserInteracting = false;
}
// function onDocumentMouseWheel( event ) {
// camera.fov += event.deltaY * 0.05;
// camera.updateProjectionMatrix();
// }
function onDocumentTouchStart(event) {
if (event.touches.length == 1) {
event.preventDefault();
onPointerDownPointerX = event.touches[0].pageX;
onPointerDownPointerY = event.touches[0].pageY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
}
function onDocumentTouchMove(event) {
if (event.touches.length == 1) {
event.preventDefault();
lon = (onPointerDownPointerX - event.touches[0].pageX) * 0.1 + onPointerDownLon;
lat = (event.touches[0].pageY - onPointerDownPointerY) * 0.1 + onPointerDownLat;
}
}
function animate() {
requestAnimationFrame(animate);
update();
}
function update() {
if (isUserInteracting === false) {
lon += 0.1;
}
lat = Math.max(-85, Math.min(85, lat));
phi = THREE.Math.degToRad(90 - lat);
theta = THREE.Math.degToRad(lon);
target.x = 500 * Math.sin(phi) * Math.cos(theta);
target.y = 500 * Math.cos(phi);
target.z = 500 * Math.sin(phi) * Math.sin(theta);
camera.position.copy(target).negate();
camera.lookAt(target);
renderer.render(scene, camera);
}
html,
body {
margin: 0;
overflow: hidden;
}
img {
width: 8vw;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
margin: auto;
}
<div id="container"></div>
<img src="https://s3-us-west-
2.amazonaws.com/s.cdpn.io/1037366/planet2.png">
I've merged both the codepens into one.
I've simply changed the class
.intro {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
background-color: black;
}
to
.intro {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
background-color: transparent;
z-index: 2;
}
When using position absolute, z-index is used to bring the object/element on top of each other (imagine a layered structure). Element with highest z-index will appear on the top of all elements with position set to absolute.
Here is more info on z-index.
Have look at this. Hope this is the desired output.

Three.js adding box to scene not working on iOS

I'm trying to get Three.js to add a box to the scene on iOS but it doesn't seem to work while on macOS Safari it does.
The scene sets up correctly and adds the first box but when adding the "cube" it doesn't appear on the scene
iOS 12.1.1 on an iPad
var scene, renderer, controls, camera;
function init() {
container = document.getElementById("canvas");
container.height = $("#canvas").height();
container.width = $("#canvas").width();
camera = new THREE.PerspectiveCamera(20, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(300, 300, 300);
scene = new THREE.Scene();
scene.background = new THREE.Color(0xfffff0);
scene.add(new THREE.AmbientLight(0x555555));
var light = new THREE.SpotLight(0xffffff, 1.5);
light.position.set(0, 500, 2000);
scene.add(light);
renderer = new THREE.WebGLRenderer({
alpha: true,
antialias: true
});
renderer.setClearColor(0xE6EEF2);
renderer.setSize($(container).width(), $(container).height());
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableKeys = false;
controls.enabled = false;
}
function addBox() {
var orientation = {
dim1: 78,
dim2: 62,
dim3: 35
}
var geom = new THREE.BoxGeometry(orientation.dim1, orientation.dim2, orientation.dim3);
geom.translate(orientation.dim1 / 2, orientation.dim2 / 2, orientation.dim3 / 2);
box_material = new THREE.MeshPhongMaterial({
transparent: true,
opacity: 0,
alphaTest: 0.5
});
mesh = new THREE.Mesh(geom, box_material)
var geometry = new THREE.EdgesGeometry(mesh.geometry);
var edges_material = new THREE.LineBasicMaterial({
color: 0x000000,
linewidth: 2
});
var edges = new THREE.LineSegments(geometry, edges_material);
mesh.name = "box1"
scene.add(mesh.add(edges));
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
controls.update();
renderer.render(scene, camera);
}
function addCube() {
pos = {
x: 46,
y: 0,
z: 0
};
orientation = orientation = {
dim1: 46,
dim2: 28,
dim3: 30
}
var geom = new THREE.BoxGeometry(orientation.dim1, orientation.dim2, orientation.dim3);
geom.translate(pos.x + orientation.dim1 / 2, pos.y + orientation.dim2 / 2, pos.z + orientation.dim3 / 2);
material = new THREE.MeshPhongMaterial({
color: Math.random() * 0xffffff,
flatShading: true,
vertexColors: THREE.VertexColors,
transparent: true,
opacity: 0.7
});
mesh = new THREE.Mesh(geom, material)
mesh.name = "cube";
scene.add(mesh);
console.log("added cube");
}
init();
animate();
addBox();
addCube();
body {
margin: 0;
}
.main {
height: 100vh;
display: flex;
position: relative;
}
.content {
display: flex;
width: 100%;
max-height: 100vh;
overflow: auto;
}
.box {
flex: 1 1 auto;
display: flex;
flex-direction: column;
border-left: 1px solid #CED4D9;
border-right: 1px solid #CED4D9;
align-items: center;
}
.boxView-container {
width: 100%;
height: auto;
flex: 1 1 auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<body>
hello2
<div id="root">
<main class="main">
<section class="content">
<div class="box">
<div class="boxView-container" id="canvas"></div>
</div>
</section>
</main>
</div>
</body>
On macOS Safari:
On iOS Safari:
jsfiddle:
http://jsfiddle.net/acrogenesis/d583wyft/44/
I think it is caused by variable scope. You need define some local variables, or else the addCube function will change some global variables above.
like var pos, mesh etc.
function addCube() {
var pos = {x: 46, y: 0, z: 0};
var orientation = {
dim1: 46,
dim2: 28,
dim3: 30
}
var geom = new THREE.BoxGeometry(orientation.dim1, orientation.dim2, orientation.dim3);
geom.translate(pos.x + orientation.dim1 / 2, pos.y + orientation.dim2 / 2, pos.z + orientation.dim3 / 2);
var material = new THREE.MeshPhongMaterial({
color: Math.random() * 0xffffff,
flatShading: true,
vertexColors: THREE.VertexColors,
transparent: true,
opacity: 0.7
});
var mesh = new THREE.Mesh(geom, material)
mesh.name = "cube";
scene.add(mesh);
console.log("added cube");
}
After define these local variables, now working great on iOS.

How to tween camera to the top in three.js

How to tween the camera to the top position with a look to the object in three.js with help of tween.js. The camera tween to the right position works perfectly.
Please use this codepen: http://codepen.io/anon/pen/ObQxjV?editors=1111
image to clarify
var camera, renderer, controls;
//scene
scene = new THREE.Scene();
//camera
camera = new THREE.OrthographicCamera(640 / -2, 640 / 2, 480 / 2, 480 / -2, -5000, 10000000);
camera.position.set(500, 500, 500);
scene.add(camera);
//renderer
renderer = new THREE.WebGLRenderer({ precision: "highp", antialias: true, preserveDrawingBuffer: false });
renderer.setSize(640, 480);
renderer.setClearColor(0xc2c2c2);
$("#canvas").append(renderer.domElement);
//controls
controls = new THREE.OrbitControls(camera, renderer.domElement, renderer, scene);
controls.target = new THREE.Vector3(250, 0, 0)
//axis
var axis = new THREE.AxisHelper( 30000 );
scene.add(axis);
//geometry
var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
var material = new THREE.MeshNormalMaterial();
var cube = new THREE.Mesh( geometry, material );
cube.position.set(250, 0, 0);
scene.add( cube );
animate();
function animate() {
camera.updateProjectionMatrix();
controls.update();
TWEEN.update();
requestAnimationFrame(animate);
render();
}
function render(){
renderer.render(scene, camera);
}
//working tween to the right
$("#workingTweenToTheRight").click(function () {
var destPos = new THREE.Vector3(500, 0, 0);
var destLookAt = new THREE.Vector3(250, 0, 0);
var currentCamPos = {
x: camera.position.x,
y: camera.position.y,
z: camera.position.z
};
var destCamPos = {
x: destPos.x,
y: destPos.y,
z: destPos.z
};
var tween = new TWEEN.Tween(currentCamPos)
.to(destCamPos, 600)
.onUpdate(function () {
camera.position.set(this.x, this.y, this.z);
camera.lookAt(destLookAt);
controls.target = destLookAt;
})
.start();
});
//not working tween to top
$("#notWorkingTweenToTheTop").click(function () {
var destPos = new THREE.Vector3(0, 500, 0);
var destLookAt = new THREE.Vector3(250, 0, 0);
var currentCamPos = {
x: camera.position.x,
y: camera.position.y,
z: camera.position.z
};
var destCamPos = {
x: destPos.x,
y: destPos.y,
z: destPos.z
};
var tween = new TWEEN.Tween(currentCamPos)
.to(destCamPos, 600)
.onUpdate(function () {
camera.position.set(this.x, this.y, this.z);
camera.lookAt(destLookAt);
controls.target = destLookAt;
})
.start();
});
body { margin: 0; }
#canvas {float: left; width: 640px; height: 380px; border: 1px solid #d3d3d3 }
.button { border: 1px solid black; cursor: pointer; width: 230px; height: 20px;}
.button:hover{background: blue; color: white;}
<script src="http://sole.github.io/tween.js/build/tween.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="http://threejs.org/build/three.min.js"></script>
<div id="canvas">
<div id="workingTweenToTheRight" class="button" >working tween to the right</div>
<div id="notWorkingTweenToTheTop" class="button" >not working tween to the top</div>
</div>
You need to set destPos for the "tween to the top" differently:
var destPos = new THREE.Vector3().addVectors(cylinder.position, new THREE.Vector3(0, 500, 0));

Three JS white screen when loading JSON object

I downloaded threejs and now try to create a 3D environment where you can move freely in some kind of "ego perspective". I used the pointlock-control example as submission and now I'm on to add my own stuff starting with a car created in Blender and exported as JSON but every time I try to load it I get just a white screen. I hope you guys can help me.
Code:
<style>
html, body {
width: 100%;
height: 100%;
}
body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
font-family: arial;
}
#blocker {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
}
#instructions {
width: 100%;
height: 100%;
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack: center;
-webkit-box-align: center;
-moz-box-align: center;
box-align: center;
color: #ffffff;
text-align: center;
cursor: pointer;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/controls/PointerLockControls.js"></script>
<div id="blocker">
<div id="instructions">
<span style="font-size:40px">Click to move</span>
<br />
(WASD or Arrow Keys = Move, SPACE = Jump, MOUSE = Look around)
</div>
</div>
<script>
var camera, scene, renderer;
var geometry, material, mesh;
var loader;
var auto;
var loadModel;
var controls,time = Date.now();
var objects = [];
var ray;
var blocker = document.getElementById( 'blocker' );
var instructions = document.getElementById( 'instructions' );
// http://www.html5rocks.com/en/tutorials/pointerlock/intro/
var havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
if ( havePointerLock ) {
var element = document.body;
var pointerlockchange = function ( event ) {
if ( document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element ) {
controls.enabled = true;
blocker.style.display = 'none';
} else {
controls.enabled = false;
blocker.style.display = '-webkit-box';
blocker.style.display = '-moz-box';
blocker.style.display = 'box';
instructions.style.display = '';
}
}
var pointerlockerror = function ( event ) {
instructions.style.display = '';
}
// Hook pointer lock state change events
document.addEventListener( 'pointerlockchange', pointerlockchange, false );
document.addEventListener( 'mozpointerlockchange', pointerlockchange, false );
document.addEventListener( 'webkitpointerlockchange', pointerlockchange, false );
document.addEventListener( 'pointerlockerror', pointerlockerror, false );
document.addEventListener( 'mozpointerlockerror', pointerlockerror, false );
document.addEventListener( 'webkitpointerlockerror', pointerlockerror, false );
instructions.addEventListener( 'click', function ( event ) {
instructions.style.display = 'none';
// Ask the browser to lock the pointer
element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;
if ( /Firefox/i.test( navigator.userAgent ) ) {
var fullscreenchange = function ( event ) {
if ( document.fullscreenElement === element || document.mozFullscreenElement === element || document.mozFullScreenElement === element ) {
document.removeEventListener( 'fullscreenchange', fullscreenchange );
document.removeEventListener( 'mozfullscreenchange', fullscreenchange );
element.requestPointerLock();
}
}
document.addEventListener( 'fullscreenchange', fullscreenchange, false );
document.addEventListener( 'mozfullscreenchange', fullscreenchange, false );
element.requestFullscreen = element.requestFullscreen || element.mozRequestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen;
element.requestFullscreen();
} else {
element.requestPointerLock();
}
}, false );
} else {
instructions.innerHTML = 'Your browser doesn\'t seem to support Pointer Lock API';
}
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xffffff, 0, 750 );
var light = new THREE.DirectionalLight( 0xffffff, 1.5 );
light.position.set( 1, 1, 1 );
scene.add( light );
var light = new THREE.DirectionalLight( 0xffffff, 0.75 );
light.position.set( -1, - 0.5, -1 );
scene.add( light );
controls = new THREE.PointerLockControls( camera );
scene.add( controls.getObject() );
ray = new THREE.Raycaster();
ray.ray.direction.set( 0, -1, 0 );
// floor
geometry = new THREE.PlaneGeometry( 2000, 2000, 100, 100 );
geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
for ( var i = 0, l = geometry.vertices.length; i < l; i ++ ) {
var vertex = geometry.vertices[ i ];
vertex.x += Math.random() * 20 - 10;
vertex.y += Math.random() * 2;
vertex.z += Math.random() * 20 - 10;
}
for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) {
var face = geometry.faces[ i ];
face.vertexColors[ 0 ] = new THREE.Color().setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 1 ] = new THREE.Color().setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 2 ] = new THREE.Color().setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 3 ] = new THREE.Color().setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
}
material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
// objects
loader = new THREE.JSONLoader( );
loadModel = function(geometry)
{
auto = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'textures/metal.jpg', new THREE.SphericalReflectionMapping() ), overdraw: true, shading: THREE.SmoothShading } ) );
mesh.scale.set(1, 1, 1);
mesh.position.set(0, 150, 0);
//mesh.rotation.set(Math.PI/2, Mat.PI/2, Math.PI/2);
//mesh.matrix.setRotationFromEuler(mesh.rotation);
scene.add( auto );
};
loader.load('blender.js/auto.js', loadModel );
setInterval(render, 50);
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
controls.isOnObject( false );
ray.ray.origin.copy( controls.getObject().position );
ray.ray.origin.y -= 10;
var intersections = ray.intersectObjects( objects );
if ( intersections.length > 0 ) {
var distance = intersections[ 0 ].distance;
if ( distance > 0 && distance < 10 ) {
controls.isOnObject( true );
}
}
controls.update( Date.now() - time );
renderer.render( scene, camera );
time = Date.now();
}
</script>
</body>
var intersections = ray.intersectObjects( objects ); but you aren't adding your mesh to objects.
Your camera does not have position nor target.
Background color of body and text "color" in instructions is same #ffffff in style.
Please change one of them, and then try :)
It may be giving out put but you may not see it,
Update:
You are adding scene here scene.add(mesh2); I think we should follow the working code(below) and redraw the scene(using loop or timer, every "0.05 second"), don't add new scene, use simple example like round to move then proceed with complex car, that may confuse sometimes..
Working Code:
loader = new THREE.JSONLoader();
loadModel = function (geometry) {
mesh2 = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
envMap : THREE.ImageUtils.loadTexture('textures/metal.refl.jpg', new THREE.SphericalReflectionMapping()),
overdraw : true,
shading : THREE.SmoothShading
}));
mesh2.scale.set(1, 1, 1);
mesh2.position.set(0, 0, 0);
//mesh.rotation.set(Math.PI/2, Mat.PI/2, Math.PI/2);
//mesh.matrix.setRotationFromEuler(mesh.rotation);
scene.add( mesh2 );
};
Comment if not solved using this

Categories

Resources