Changing camera rotation with GUI

Hello!

I’m having trouble setting the camera in my project to the right rotation.

I tried with the ThreeJS editor and copy/paste the values in my project’s code but the result is totally different. So I forked the example code from threejsfundamentals.org, trying to set up a live editor with a GUI but the camera’s rotation goes bananas with the code I have by now:

<!DOCTYPE html>
<canvas id="c"></canvas>
<div class="split">
    <div id="view1" tabindex="1"></div>
    <div id="view2" tabindex="2"></div>
</div>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <title>Camera Live Positioner</title>
    <link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
    <script type="module">
        import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
        import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/controls/OrbitControls.js';
        import { GUI } from 'https://threejsfundamentals.org/threejs/../3rdparty/dat.gui.module.js';

    function main() {
        const canvas = document.querySelector('#c');
        const view1Elem = document.querySelector('#view1');
        const view2Elem = document.querySelector('#view2');
        const renderer = new THREE.WebGLRenderer({ canvas });

        const fov = 45;
        const aspect = 2;  // the canvas default
        const near = 5;
        const far = 100;
        const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
        camera.position.set(0, 10, 20);

        const cameraHelper = new THREE.CameraHelper(camera);

        var gui = new GUI();

        var cameraController = {

            rotationX: 0
        };

        function cameraChanger() {
            //console.log(cameraController['rotationX']);
            camera.rotateX(cameraController['rotationX']);
        }

        gui.add(cameraController, 'rotationX', 0, 90, 1).onChange(cameraChanger);

        const controls = new OrbitControls(camera, view1Elem);
        controls.target.set(0, 5, 0);
        controls.update();

        const camera2 = new THREE.PerspectiveCamera(
            60,  // fov
            2,   // aspect
            0.1, // near
            500, // far
        );
        camera2.position.set(40, 10, 30);
        camera2.lookAt(0, 5, 0);

        const controls2 = new OrbitControls(camera2, view2Elem);
        controls2.target.set(0, 5, 0);
        controls2.update();

        const scene = new THREE.Scene();
        scene.background = new THREE.Color('black');
        scene.add(cameraHelper);

        {
            const planeSize = 40;

            const loader = new THREE.TextureLoader();
            const texture = loader.load('https://threejsfundamentals.org/threejs/resources/images/checker.png');
            texture.wrapS = THREE.RepeatWrapping;
            texture.wrapT = THREE.RepeatWrapping;
            texture.magFilter = THREE.NearestFilter;
            const repeats = planeSize / 2;
            texture.repeat.set(repeats, repeats);

            const planeGeo = new THREE.PlaneBufferGeometry(planeSize, planeSize);
            const planeMat = new THREE.MeshPhongMaterial({
                map: texture,
                side: THREE.DoubleSide,
            });
            const mesh = new THREE.Mesh(planeGeo, planeMat);
            mesh.rotation.x = Math.PI * -.5;
            scene.add(mesh);
        }
        {
            const cubeSize = 4;
            const cubeGeo = new THREE.BoxBufferGeometry(cubeSize, cubeSize, cubeSize);
            const cubeMat = new THREE.MeshPhongMaterial({ color: '#8AC' });
            const mesh = new THREE.Mesh(cubeGeo, cubeMat);
            mesh.position.set(cubeSize + 1, cubeSize / 2, 0);
            scene.add(mesh);
        }
        {
            const sphereRadius = 3;
            const sphereWidthDivisions = 32;
            const sphereHeightDivisions = 16;
            const sphereGeo = new THREE.SphereBufferGeometry(sphereRadius, sphereWidthDivisions, sphereHeightDivisions);
            const sphereMat = new THREE.MeshPhongMaterial({ color: '#CA8' });
            const mesh = new THREE.Mesh(sphereGeo, sphereMat);
            mesh.position.set(-sphereRadius - 1, sphereRadius + 2, 0);
            scene.add(mesh);
        }

        {
            const color = 0xFFFFFF;
            const intensity = 1;
            const light = new THREE.DirectionalLight(color, intensity);
            light.position.set(0, 10, 0);
            light.target.position.set(-5, 0, 0);
            scene.add(light);
            scene.add(light.target);
        }

        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 setScissorForElement(elem) {
            const canvasRect = canvas.getBoundingClientRect();
            const elemRect = elem.getBoundingClientRect();

            // compute a canvas relative rectangle
            const right = Math.min(elemRect.right, canvasRect.right) - canvasRect.left;
            const left = Math.max(0, elemRect.left - canvasRect.left);
            const bottom = Math.min(elemRect.bottom, canvasRect.bottom) - canvasRect.top;
            const top = Math.max(0, elemRect.top - canvasRect.top);

            const width = Math.min(canvasRect.width, right - left);
            const height = Math.min(canvasRect.height, bottom - top);

            // setup the scissor to only render to that part of the canvas
            const positiveYUpBottom = canvasRect.height - bottom;
            renderer.setScissor(left, positiveYUpBottom, width, height);
            renderer.setViewport(left, positiveYUpBottom, width, height);

            // return the aspect
            return width / height;
        }

        function render() {

            resizeRendererToDisplaySize(renderer);

            // turn on the scissor
            renderer.setScissorTest(true);

            // render the original view
            {
                const aspect = setScissorForElement(view1Elem);

                // adjust the camera for this aspect
                camera.aspect = aspect;
                camera.updateProjectionMatrix();
                cameraHelper.update();

                // don't draw the camera helper in the original view
                cameraHelper.visible = false;

                scene.background.set(0x000000);

                // render
                renderer.render(scene, camera);
            }

            // render from the 2nd camera
            {
                const aspect = setScissorForElement(view2Elem);

                // adjust the camera for this aspect
                camera2.aspect = aspect;
                camera2.updateProjectionMatrix();

                // draw the camera helper in the 2nd view
                cameraHelper.visible = true;

                scene.background.set(0x000040);

                renderer.render(scene, camera2);
            }

            requestAnimationFrame(render);
        }

        requestAnimationFrame(render);
    }

    main();
    </script>
</body>
</html>

CSS looks like this:

html, body {
margin: 0;
height: 100%;
}

#c {
width: 100%;
height: 100%;
display: block;
}

.split {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
}

.split > div {
width: 100%;
height: 100%;
}

Hope somebody can help! :slight_smile: