Skip to content

Commit

Permalink
fix: relocate camera on window resize (#1160)
Browse files Browse the repository at this point in the history
Co-authored-by: Mario <[email protected]>
  • Loading branch information
VmMad and msarcev authored Feb 22, 2024
1 parent 4c3af8c commit 20efea8
Showing 1 changed file with 40 additions and 18 deletions.
58 changes: 40 additions & 18 deletions client/src/features/visualizer-threejs/CameraControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,56 @@ import { getCameraAngles } from "./utils";
import React, { useEffect } from "react";
import { useThree } from "@react-three/fiber";
import { CanvasElement } from "./enums";
import { useTangleStore } from "./store";
import { VISUALIZER_PADDINGS } from "./constants";

const CAMERA_ANGLES = getCameraAngles();

const CameraControls = () => {
const [shouldLockZoom, setShouldLockZoom] = React.useState<boolean>(false);
const controls = React.useRef<DreiCameraControls>(null);

const CAMERA_ANGLES = getCameraAngles();
const scene = useThree((state) => state.scene);
const mesh = scene.getObjectByName(CanvasElement.TangleWrapperMesh) as THREE.Mesh | undefined;

const zoom = useTangleStore((s) => s.zoom);
const get = useThree((state) => state.get);
const mesh = get().scene.getObjectByName(CanvasElement.TangleWrapperMesh);
/**
* Locks the camera zoom to the current zoom value.
*/
function lockCameraZoom(controls: DreiCameraControls) {
const zoom = controls.camera.zoom;
controls.maxZoom = zoom;
controls.minZoom = zoom;
}

// Set fixed zoom
useEffect(() => {
if (controls.current && shouldLockZoom) {
controls.current.maxZoom = zoom;
controls.current.minZoom = zoom;
/**
* Unlocks the camera zoom for free movement.
*/
function unlockCameraZoom(controls: DreiCameraControls) {
controls.maxZoom = Infinity;
controls.minZoom = 0.01;
}

/**
* Fits the camera to the TangleMesh.
*/
function fitCameraToTangle(controls: DreiCameraControls | null, mesh?: THREE.Mesh) {
if (controls && mesh) {
unlockCameraZoom(controls);
controls.fitToBox(mesh, false, { ...VISUALIZER_PADDINGS });
controls.setOrbitPoint(0, 0, 0);
lockCameraZoom(controls);
}
}, [controls, zoom, shouldLockZoom]);
}

// Fix to TangleMesh
/**
* Fit camera to TangleMesh on mount and on window resize.
*/
useEffect(() => {
if (controls.current && mesh) {
controls.current.fitToBox(mesh, false, { ...VISUALIZER_PADDINGS });
controls.current.setOrbitPoint(0, 0, 0);
setShouldLockZoom(true);
}
const adjustCamera = () => fitCameraToTangle(controls.current, mesh);
adjustCamera();

window.addEventListener("resize", adjustCamera);
return () => {
window.removeEventListener("resize", adjustCamera);
};
}, [controls, mesh]);

return <DreiCameraControls ref={controls} makeDefault {...CAMERA_ANGLES} />;
Expand Down

0 comments on commit 20efea8

Please sign in to comment.