I am using Three.js to develop a cube that translates and rotate in 3D space using data from accelerometer and gyroscope data.
So far I have one canvas that shows the accelerometer movement. Now I need to have another canvas that shows the gyroscope data on a separate canvas, I prefer to have two JS code for each canvas, so they are independent of each other. I wasn’t able to make two separate canvases, and I don’t know if it is even possible to use two different javascript codes in the html.
Below is how my HTML is structured:
HTML
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <canvas id="canvas" width="500" height="800" style="border:1px solid #eb1c1c;"></canvas> <div id="info"> <div>t = <span id="time">0</span> s</div> <div>accX = <span id="accX">0</span></div> <div>accY = <span id="accY">0</span></div> <div>accZ = <span id="accZ">0</span></div> </div> </body> </html>
and this is the javascript:
import * as THREE from "three"; import data from "../data/data.json" import "./style.css" var width = window.innerWidth; var height = window.innerHeight; const canvas = document.querySelector('#canvas'); const renderer = new THREE.WebGLRenderer({ canvas }); renderer.setSize (width, height); var planeSize = 100000 const fov = 70; const aspect = 2; // the canvas default const near = 20; const far = 500; const camera = new THREE.PerspectiveCamera(70, width/height, 1, 10000); camera.position.y = 3; camera.position.z = 30; camera.lookAt (new THREE.Vector3(0,0,0)); // camera.position.set(0, 40, 1.5); // camera.up.set(0, 10, 1); // camera.lookAt(0, 10, 0); const scene = new THREE.Scene(); { const color = 0x00afaf; const intensity = 10; const size = 10; const divisions = 10; const gridHelper = new THREE.GridHelper( planeSize, 5000 ); gridHelper.setColors( new THREE.Color(0xff0000), new THREE.Color(0xffffff) ); scene.add(gridHelper); const light = new THREE.PointLight(color, intensity); scene.add(light); // scene.add( gridHelper ); } // // label the axis // var textGeo = new THREE.TextGeometry('Y', { // size: 5, // height: 2, // curveSegments: 6, // font: "helvetiker", // style: "normal" // }); // var color = new THREE.Color(); // color.setRGB(255, 250, 250); // var textMaterial = new THREE.MeshBasicMaterial({ color: color }); // var text = new THREE.Mesh(textGeo , textMaterial); // text.position.x = axis.geometry.vertices[1].x; // text.position.y = axis.geometry.vertices[1].y; // text.position.z = axis.geometry.vertices[1].z; // text.rotation = camera.rotation; // scene.add(text); const boxGeometry = new THREE.BoxGeometry(); const boxMaterial = new THREE.MeshBasicMaterial({ color: "green", wireframe: false }); const object = new THREE.Mesh(boxGeometry, boxMaterial); var cubeAxis = new THREE.AxesHelper(3); object.add(cubeAxis); object.scale.set(5, 5, 5) scene.add(object); scene.background = new THREE.Color(0.22, 0.23, 0.22); let currentIndex = 0 let time = data[currentIndex].time let velocity = new THREE.Vector3() requestAnimationFrame(render); function render(dt) { dt *= 0.0001 // in seconds time += dt document.querySelector("#time").textContent = time.toFixed(2) // Find datapoint matching current time while (data[currentIndex].time < time) { currentIndex++ if (currentIndex >= data.length) return } const { rotX, rotY, rotZ, accX, accY, accZ } = data[currentIndex] document.querySelector("#accX").textContent = accX* 10; document.querySelector("#accY").textContent = accY* 10; document.querySelector("#accZ").textContent = accZ* 10; const acceleration = new THREE.Vector3() // object.rotation.set( rotX, rotY, rotZ) object.position.x = accX * 30; // object.position.add(velocity.clone().multiplyScalar(dt)).add(acceleration.clone().multiplyScalar(50 * dt ** 2)) // object.position.add(accZ) // velocity.add(acceleration.clone().multiplyScalar(dt)) var relativeCameraOffset = new THREE.Vector3 (0,10,10); var cameraOffset = relativeCameraOffset.applyMatrix4( object.matrixWorld ); camera.position.x = cameraOffset.x; camera.position.y = cameraOffset.y; camera.position.z = cameraOffset.z; camera.lookAt( object.position ); resizeToClient(); renderer.render(scene, camera); requestAnimationFrame(render); } function resizeToClient() { const needResize = resizeRendererToDisplaySize() if (needResize) { const canvas = renderer.domElement; camera.aspect = canvas.clientWidth / canvas.clientHeight; camera.updateProjectionMatrix(); } } function resizeRendererToDisplaySize() { 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; }
this is how I want the canvas to look like:
Advertisement
Answer
Good news is it is possible, you just have to put all your code(at least animations) in separate functions :
const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); const scene1 = new THREE.Scene(); const camera1 = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); scene.background = new THREE.Color( 0xf0000f); scene1.background = new THREE.Color( 0x0000ff ); const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); const renderer1 = new THREE.WebGLRenderer(); renderer1.setSize( window.innerWidth, window.innerHeight ); renderer1.domElement.width=500; renderer1.domElement.height=300; renderer1.domElement.style.position="absolute"; renderer1.domElement.style.top=0; renderer1.domElement.style.height=150+"px"; renderer1.domElement.style.width=200+"px"; renderer.domElement.width=500; renderer.domElement.height=300; renderer.domElement.style.position="absolute"; renderer.domElement.style.top=0; document.body.appendChild( renderer.domElement ); document.body.appendChild( renderer1.domElement ); const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); const geometry1 = new THREE.BoxGeometry(3,3,3); const material1 = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube1 = new THREE.Mesh( geometry1, material1 ); scene1.add( cube1 ); camera.position.z = 5; camera1.position.z = 5; const animate = function () { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); }; const animate1 = function () { requestAnimationFrame( animate1 ); cube1.rotation.x += 0.01; cube1.rotation.y += 0.01; renderer1.render( scene1, camera1 ); }; animate(); animate1();
<script src="http://threejs.org/build/three.min.js"></script>