<div>
  
</div>
body {
  padding:0; margin: 0;
  overflow:hidden;
}
canvas {
  //width: 100%;
    //height: 100%;
}
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);

const screenDimensions = {
  width: canvas.clientWidth,
  height: canvas.clientWidth
}

const aspectRatio = screenDimensions.width / screenDimensions.height;
const fieldOfView = 90;
const nearPlane = 1;
const farPlane = 1000; 

const renderer = 
      new THREE.WebGLRenderer({
        canvas: canvas, 
        antialias:true,
      });
    
    renderer.setPixelRatio(window.devicePixelRatio ? window.devicePixelRatio : 1);
    renderer.setSize(screenDimensions.width, screenDimensions.height);
    renderer.gammaInput = true;
    renderer.gammaOutput = true; 

let scene = new THREE.Scene();

const camera = createCamera();
const camera2 = createCamera();

const cams = [camera, camera2];

updateProjection();

window.addEventListener("resize", updateProjection);

window.addEventListener("mousemove", orbitCamera);

function createCamera(aspect = screenDimensions.width / screenDimensions.height, fov = 90, near = 1, far = 1000) {

  return new THREE.PerspectiveCamera(fov, aspect, near, far);
}

function updateProjection(event) {
 canvas.style.width = "100vw";
 canvas.style.height = "100vh";
  canvas.width = canvas.offsetWidth;
  canvas.height = canvas.offsetHeight;

  const { clientWidth, clientHeight } = canvas; 

  screenDimensions.width = clientWidth;
  screenDimensions.height = clientHeight;
  
  cams.forEach((c)=>{
      c.aspect = clientWidth / clientHeight;
      c.updateProjectionMatrix();
  })



  renderer.setSize(clientWidth, clientHeight);
}

let light = new THREE.PointLight(0x00ffff, 12, 100);
                light.position.x = 5;
                light.position.y = 5;

let light2 = new THREE.PointLight(0xff00ff, 12, 100);
                light2.position.x = 5;
                light2.position.z = -5;

let light3 = new THREE.PointLight(0xffff00, 12, 100);
                light3.position.z = 5;
                light3.position.y = -5;

var lightGroup = new THREE.Group();

    lightGroup.add(light);
    lightGroup.add(light2);
    lightGroup.add(light3);

var geometry = new THREE.IcosahedronBufferGeometry(1, 2);
var material = new THREE.MeshStandardMaterial( { roughness: 0.5,color: 0x101010 } );
var cube = new THREE.Mesh( geometry, material );
var group = new THREE.Object3D();

var sphereSize = 1;
var pointLightHelper = new THREE.PointLightHelper( light, sphereSize );
var pointLightHelper2 = new THREE.PointLightHelper( light2, sphereSize );
var pointLightHelper3 = new THREE.PointLightHelper( light3, sphereSize );

lightGroup.add( pointLightHelper );
lightGroup.add( pointLightHelper2 );
lightGroup.add( pointLightHelper3 );

scene.background = new THREE.Color( 0x232330 );

window.addEventListener("mousedown", ()=>{showCam = !showCam;})

group.add(camera);

camera.position.z = 15;

scene.add( lightGroup );
scene.add( group );
scene.add( cube );

camera2.position.x = 0;
camera2.position.y = 20;
camera2.position.z = 20;

camera2.lookAt(new THREE.Vector3());

cameraHelper = new THREE.CameraHelper( camera );
cameraHelper.visible = false;
scene.add( cameraHelper );

let target = new THREE.Vector2();
let current = new THREE.Vector2();

let cameraY

let showCam = false;

function orbitCamera(e) {
  const { clientX, clientY } = e;
  target.x = (clientX / window.innerWidth);
  target.y = (clientY / window.innerHeight);
}
t=0;

group.rotation.z =0.1

function animate() {
  requestAnimationFrame(animate);
  t+=0.01;
  //lightGroup.rotateX(0.01)
  camera.rotation.y = -0.3 * camera.aspect;
 //camera.rotation.x = Math.cos(t)*0.16;

  
  let offset = new THREE.Vector2().subVectors(target,current);
      offset.multiplyScalar(0.1);
  
  current.add(offset);
  
  group.rotation.y = -current.x *  (Math.PI*Math.PI);
  camera.position.z = 5 + (current.y *  (Math.PI*Math.PI)) * 2;
  //group.rotation.x = (current.y *  (Math.PI*Math.PI));
  if(showCam) {
    cameraHelper.visible = true;
    renderer.render(scene, camera2);
  } else {
    cameraHelper.visible = false;
    renderer.render(scene, camera);
  }
  
}

animate();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js