JanuszFrontEnd'u
JanuszFrontEnd'u

Reputation: 471

Threejs - rotating the camera by 90 degrees, not objects

In my project there are a lot of objects in the scene so I'd rather rotate the camera than the objects. How can I do that? I use an OrthographicCamera, which means I work on 2D.

Current camera position (example left)

const camera =  new OrthographicCamera(0, width, 0, height, 0, 20);
camera.position.set(x, y, 1);
camera.clearViewOffset();
camera.updateProjectionMatrix();

On the right is what I would like to achieve...

enter image description here

When I use camera.rotation.z = Math.PI * 0.5; Objects disappear behind viewport because my camera is set to the top left corner. Unfortunately, the camera settings is due to the coordinates it gets from BE.

Upvotes: 2

Views: 5091

Answers (2)

user128511
user128511

Reputation:

Because your frustum has 0,0 at the top left you need to add some other parents to the camera move its rotation point.

const {
  Object3D,
  OrthographicCamera,
  Scene,
  Renderer,
  GridHelper,
  WebGLRenderer,
  MathUtils,
} = THREE;
const {
  lerp,
} = MathUtils;

const canvas = document.querySelector('canvas')
const {width, height} = canvas.getBoundingClientRect();
const scene = new Scene();

const camera = new OrthographicCamera(0, width, 0, height, 0, 20);
// cameras look down -Z so this camera is looking from 20 to 0
camera.position.z = 20;

const cameraBase = new Object3D();
const cameraPivot = new Object3D();
cameraBase.add(cameraPivot);
cameraBase.position.set(width / 2, height / 2, 0);
cameraPivot.add(camera);
cameraPivot.position.set(-width / 2, -height / 2, 0);
scene.add(cameraBase);


addRect('red',    -10, -10, 5,  20,  20);
addRect('cyan',    20,  20, 5,  20,  20);
addRect('green',  100,  50, 5,  25,  30);
addRect('yellow', 130,  70, 6, 100,  50);
addRect('orange', 170,  90, 7,  50,  75);
addRect('white',    1,   1, 5, 298, 148);

function addRect(color, x, y, z, width, height) {
  // make a 1x1 unit grid
  const grid = new GridHelper(1, 1, color, color);
  // move it so it starts at 0,0 and goes to 1,1
  grid.geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(0.5, 0, 0.5));
  // grids are in x,z plane. rotate to x,y plane
  grid.rotation.x = Math.PI * -0.5;
  // position it
  grid.position.set(x, y, z);
  // make it the size we want in pixel units
  grid.scale.set(width, 1, height);
  scene.add(grid);
}

const renderer = new WebGLRenderer({canvas});


function render(now) {
  cameraBase.rotation.z = (now * 0.001);
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}
requestAnimationFrame(render);
body { background: #444; }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.js"></script>
<canvas></canvas>

Upvotes: 1

Mugen87
Mugen87

Reputation: 31026

Try it with:

camera.rotation.z = Math.PI * 0.5;

const aspect = window.innerWidth / window.innerHeight;
const frustumSize = 2;

const camera = new THREE.OrthographicCamera(0.5 * frustumSize * aspect / -2, 0.5 * frustumSize * aspect / 2, frustumSize / 2, frustumSize / -2, 0.01, 10);
camera.position.z = 1;
camera.rotation.z = Math.PI * 0.5;

const scene = new THREE.Scene();

scene.add(new THREE.AxesHelper());

const renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

renderer.render(scene, camera);
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.js"></script>

Upvotes: 2

Related Questions