Rezise window (Three Viewport Gizmo)

I’m using the Three Viewport Gizmo library with React Three Fiber, everything works normally but when I render the Gizmo and resize the window the objects in the scene are distorted. I’ve tried updating the camera aspect ratio but it didn’t work.

I managed to solve the problem. Here is my code:

Gizmo.jsx


import { useEffect, useRef } from 'react'
import { useThree, useFrame } from '@react-three/fiber'
import { ViewportGizmo } from 'three-viewport-gizmo'

export const Gizmo = () => {
  const { camera, gl, scene, controls } = useThree()
  const gizmoRef = useRef()

  useEffect(() => {
    const gizmo = new ViewportGizmo(camera, gl)
    gizmoRef.current = gizmo

    const resize = () => {
      const width = window.innerWidth
      const height = window.innerHeight - 1
      camera.aspect = width / height
      camera.updateProjectionMatrix()
      gl.setSize(width, height)
      gizmo.update()
    }

    if (controls) {
      gizmo.addEventListener('start', () => (controls.enabled = false))
      gizmo.addEventListener('end', () => (controls.enabled = true))
      gizmo.addEventListener('change', () => {
        controls.setPosition(...camera.position.toArray())
      })
      controls.addEventListener('update', () => {
        controls.getTarget(gizmo.target)
        gizmo.update()
      })
    }

    window.addEventListener('resize', resize)

    return () => {
      window.removeEventListener('resize', resize)
    }
  }, [camera, gl, scene, controls])

  useFrame(() => {
    if (gizmoRef.current) {
      gl.render(scene, camera)
      gizmoRef.current.render()
    }
  }, true)

  return null
}

App.jsx

import React, { useRef } from 'react'
import { Canvas } from '@react-three/fiber'
import { CameraControls } from '@react-three/drei'
import { Gizmo } from './Gizmo'
import * as THREE from 'three'

import './App.css'

function App() {
  THREE.Object3D.DEFAULT_UP.set(0, 0, 1)

  const controlsRef = useRef()

  return (
    <>
      <Canvas>
        <color attach="background" args={['#303030']} />
        <CameraControls makeDefault ref={controlsRef} />
        <mesh>
          <boxGeometry />
          <meshBasicMaterial color={'red'} />
        </mesh>
        <axesHelper />
        <Gizmo />
      </Canvas>
    </>
  )
}

export default App

1 Like