Achieving a Full-Screen Three.js Canvas in React: A step-by-step guide on spanning the view height and width of a webpage

I've been working on tweaking the code found in this particular example:

How to connect Threejs to React?

This is the snippet of code I am focusing on:

import React, { Component } from 'react'
import * as THREE from 'three'

class Scene extends Component {
constructor(props) {
super(props)

this.start = this.start.bind(this)
this.stop = this.stop.bind(this)
this.animate = this.animate.bind(this)
}

componentDidMount() {
const width = this.mount.clientWidth
const height = this.mount.clientHeight

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
  75,
  width / height,
  0.1,
  1000
)
const renderer = new THREE.WebGLRenderer({ antialias: true })
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: '#433F81' })
const cube = new THREE.Mesh(geometry, material)

camera.position.z = 4
scene.add(cube)
renderer.setClearColor('#000000')
renderer.setSize(width, height)

this.scene = scene
this.camera = camera
this.renderer = renderer
this.material = material
this.cube = cube

this.mount.appendChild(this.renderer.domElement)
this.start()
}

componentWillUnmount() {
this.stop()
this.mount.removeChild(this.renderer.domElement)
}

start() {
if (!this.frameId) {
  this.frameId = requestAnimationFrame(this.animate)
}
}

stop() {
  cancelAnimationFrame(this.frameId)
}

animate() {
this.cube.rotation.x += 0.01
this.cube.rotation.y += 0.01

this.renderScene()
this.frameId = window.requestAnimationFrame(this.animate)
}

renderScene() {
  this.renderer.render(this.scene, this.camera)
}

render() {
return (
  <div
    style={{ width: '400px', height: '400px' }}
    ref={(mount) => { this.mount = mount }}
  />
)
}
}

export default Scene

I have been attempting to adjust the canvas size to fit the full viewport height and width for background purposes.

In my progress, I decided to utilize the npm package

npm install react-native-responsive-view-port --save

and made the following modifications:

  render() {
    return (
      <div
        style={{ width: vh(100), height: vw(100), }}
        ref={(mount) => { this.mount = mount }}
      />
    )
  }

Despite trying to make it responsive using percentages, I encountered the error:

Module not found: Can't resolve 'react-native-expo-viewport-units' in 'C:\Users\Gabriel\Desktop\grid_site\src\pages'

If anyone has a solution to help me achieve a responsive layout with Three Js canvas spanning the entire browser window, I would greatly appreciate it!

Answer №1

You have the option to utilize the same units and measurements, but by using the built-in CSS rather than a JavaScript function, within the style attribute:

vh(100) can be replaced with 100vh, vw(100) with 100vw.

One possible reason for the unavailability of the package is that it may be designed specifically for use in React Native.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to trigger a click handler before the completion of the ripple effect in Material UI?

When using the <FlatButtin> control (or any other similar control), the click handler or redirection does not trigger immediately. Instead, it waits for the visual "ripple" effect to finish. This delay in user interaction makes the UI I'm devel ...

Preventing cross-site scripting attacks with the help of dynamic pre elements

An expert recommended that the user content, replyContent, be surrounded by a <pre> tag to prevent XSS attacks. However, why is it commonly believed that this code effectively prevents XSS? I attempted to inject </pre><script>alert("XSS" ...

Encountering an issue with the SSR module evaluation despite having SSR disabled in Svelte Kit

I needed a specific route in my app to not be server-side rendered. This can be achieved by setting export const ssr = false in the module script or configuring ssr: false in the svelte.config.js, as outlined in the Svelte documentation. Despite disabling ...

Whenever I press a button, my card holder gradually slides downwards

I'm facing an issue with my code and I'm unsure whether it's related to CSS or JavaScript. Whenever I click the button on my page, my card-container2 moves downward unexpectedly. Here is the snippet of my code: HTML: <div class="car ...

Implementing a 'Load More' button for a list in Vue.js

I am currently working on adding a load more button to my code. While I could achieve this using JavaScript, I am facing difficulties implementing it in Vue.js. Here is the Vue code I have been working with. I attempted to target the element with the compa ...

Puzzling blank area found beneath the form component

There seems to be some extra space at the bottom of a form when it's placed inside a div. How can we remove that unwanted space? In examples from stack overflow, the extra space is not visible in the code snippets provided. However, it appears elsewh ...

What methods can I use to minimize the frequency of the blue box appearing around text?

I successfully developed code that enables user interaction with text, triggering the opening of a modal box when clicked. In this modal box, the text turns red upon clicking, indicating activation of a checkbox. However, I notice that every time I intera ...

Blank space on the lower portion of my website as I attempt to implement a responsive layout

Working on making my webpage responsive for iPad and mobile devices. While adjusting the media query, I noticed a white area at the bottom of the page that seems to be outside the body element. Unsure of where it's coming from. Any help would be great ...

Meteor Routing Issue: The path "/"" you are trying to access does not exist in the routing system

After upgrading Meteor to version 1.3.2.4, I encountered an issue where the error message "Error : There is no route for the path: /" appeared. I made sure to update all packages to their latest versions as well. I tested the application in both "meteor" ...

Having trouble with the line of code right before a $timeout in AngularJS

I am wondering about an issue in my code. vm.showSuccess = true; $timeout(function() { close(); }, 2000); vm.showSuccess = false; Interestingly, the timeout function is executing properly but the first line seems to be ignored. This piece of code is me ...

Effortlessly adjust the top margin of the div element

I have been attempting to smoothly move a div (circle), but I'm facing difficulties. The div instantly jumps to the final position instead of moving smoothly. In an effort to simulate the process of a ball falling, I tried using the animate method wi ...

JavaScript array displaying excess whitespace in its presentation

https://i.sstatic.net/5AdA7.png One issue I am facing is that when I use console.log(a), it adds extra spaces which then flow through to the backend. This leads to each element breaking after the first one. How can I resolve this problem and why does it o ...

Issue with Bootstrap 5 spinner's lack of motion in Firefox browser

Essentially, the issue is that a very simple Bootstrap 5 spinner does not spin in Firefox. It works fine in Chromium and all other Bootstrap components work well in Firefox as well. Here is the html code (identical to Bootstrap docs): <div class=&q ...

Information failed to load into the datatable

i've implemented this code snippet to utilize ajax for loading data into a datatable. However, I'm encountering an issue where the data is not being loaded into the database. $('#new_table').DataTable({ "processing": true, "ser ...

How can I create a box-shaped outline using Three.js?

As someone new to threejs, I have been trying to figure out how to render a transparent box around a symbol in my canvas. The box should only display a border and the width of this border should be customizable. Currently, I am using wireframe to create a ...

The Cloudinary setup does not retrieve information from the .env file

I am currently integrating Cloudinary with my node.js project... Unfortunately, I have encountered an issue where cloudinary.config is not able to read data from the .env file. Instead, I am required to input them directly into the code! const cloudinary ...

Is there a way to enable ad-block plugins to effectively hide an entire div from visitors, preventing the website from appearing incomplete?

I have set up a div element specifically for ads, giving it some padding and a border to make it stand out. Surprisingly, this approach is not counter-productive. However, considering the percentage of users who use adblock, I am concerned that they will ...

implementing a smooth transition effect for image changes upon hover

I've been working on a React project where I created a card that changes its image when hovered over. I wanted to add a smoother transition effect to the image change using transition: opacity 0.25s ease-in-out;, but it doesn't seem to be working ...

Using Reactjs to bind onClick event to a list component generated dynamically

If I have a render function that resembles the following: render() { var user_rows = [] this.state.user_list.forEach((user, index) => { user_rows.push( <tr key={user}> <td><div className="bt ...

Tips for pinpointing parent elements within a group of various sub child elements

CSS - <div class="windows" id="window'+divCount+'"> <p id="windowName'+divCount+'"></p> <p id="para'+divCount+'">Source</p> </div> <div cla ...