Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@react-three/fiber
Advanced tools
@react-three/fiber is a React renderer for Three.js, enabling the creation of 3D graphics and animations using React components. It simplifies the process of integrating Three.js with React, allowing developers to leverage React's declarative approach to build complex 3D scenes.
Creating a Basic 3D Scene
This code demonstrates how to create a basic 3D scene with two boxes using @react-three/fiber. The `Canvas` component sets up the 3D rendering context, and the `Box` component from `@react-three/drei` is used to add 3D objects to the scene.
```jsx
import React from 'react';
import { Canvas } from '@react-three/fiber';
import { Box } from '@react-three/drei';
function App() {
return (
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
);
}
export default App;
```
Animating Objects
This code shows how to animate a 3D object using @react-three/fiber. The `useFrame` hook is used to update the rotation of the box on every frame, creating a continuous animation.
```jsx
import React, { useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
function RotatingBox() {
const mesh = useRef();
useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01));
return (
<mesh ref={mesh}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={'orange'} />
</mesh>
);
}
function App() {
return (
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<RotatingBox />
</Canvas>
);
}
export default App;
```
Loading 3D Models
This code demonstrates how to load and display a 3D model using @react-three/fiber. The `useGLTF` hook from `@react-three/drei` is used to load a GLTF model, which is then added to the scene using the `primitive` component.
```jsx
import React from 'react';
import { Canvas } from '@react-three/fiber';
import { useGLTF } from '@react-three/drei';
function Model() {
const { scene } = useGLTF('/path/to/model.glb');
return <primitive object={scene} />;
}
function App() {
return (
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Model />
</Canvas>
);
}
export default App;
```
Three.js is a popular JavaScript library for creating 3D graphics in the browser. Unlike @react-three/fiber, which integrates with React, Three.js is a standalone library that requires imperative programming to create and manage 3D scenes.
react-three-renderer is another React renderer for Three.js, similar to @react-three/fiber. However, it is less actively maintained and has fewer features compared to @react-three/fiber, which has a more modern API and better integration with the React ecosystem.
aframe-react is a React binding for A-Frame, a web framework for building virtual reality experiences. While @react-three/fiber focuses on 3D graphics with Three.js, aframe-react is geared towards VR applications and provides a higher-level abstraction for creating immersive experiences.
react-three-fiber is a React renderer for threejs.
Build your scene declaratively with re-usable, self-contained components that react to state, are readily interactive and can participate in React's ecosystem.
npm install three @react-three/fiber
None. Everything that works in Threejs will work here without exception.
No. There is no overhead. Components render outside of React. It outperforms Threejs in scale due to Reacts scheduling abilities.
Yes. It merely expresses Threejs in JSX: <mesh />
becomes new THREE.Mesh()
, and that happens dynamically. If a new Threejs version adds, removes or changes features, it will be available to you instantly without depending on updates to this library.
Let's make a re-usable component that has its own state, reacts to user-input and participates in the render-loop. (live demo). |
import { createRoot } from 'react-dom/client'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
function Box(props) {
// This reference gives us direct access to the THREE.Mesh object
const ref = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => (ref.current.rotation.x += delta))
// Return the view, these are regular Threejs elements expressed in JSX
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
createRoot(document.getElementById('root')).render(
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>,
)
npm install @types/three
import * as THREE from 'three'
import { createRoot } from 'react-dom/client'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame, ThreeElements } from '@react-three/fiber'
function Box(props: ThreeElements['mesh']) {
const ref = useRef<THREE.Mesh>(null!)
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
useFrame((state, delta) => (ref.current.rotation.x += delta))
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
createRoot(document.getElementById('root') as HTMLElement).render(
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>,
)
Live demo: https://codesandbox.io/s/icy-tree-brnsm?file=/src/App.tsx
This example relies on react 18 and uses expo-cli
, but you can create a bare project with their template or with the react-native
CLI.
# Install expo-cli, this will create our app
npm install expo-cli -g
# Create app and cd into it
expo init my-app
cd my-app
# Install dependencies
npm install three @react-three/fiber@beta react@rc
# Start
expo start
Some configuration may be required to tell the Metro bundler about your assets if you use useLoader
or Drei abstractions like useGLTF
and useTexture
:
// metro.config.js
module.exports = {
resolver: {
sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx', 'cjs'],
assetExts: ['glb', 'png', 'jpg'],
},
}
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber/native'
function Box(props) {
const mesh = useRef(null)
const [hovered, setHover] = useState(false)
const [active, setActive] = useState(false)
useFrame((state, delta) => (mesh.current.rotation.x += delta))
return (
<mesh
{...props}
ref={mesh}
scale={active ? 1.5 : 1}
onClick={(event) => setActive(!active)}
onPointerOver={(event) => setHover(true)}
onPointerOut={(event) => setHover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
export default function App() {
return (
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
)
}
Visit docs.pmnd.rs
You need to be versed in both React and Threejs before rushing into this. If you are unsure about React consult the official React docs, especially the section about hooks. As for Threejs, make sure you at least glance over the following links:
Some reading material:
@react-three/gltfjsx
– turns GLTFs into JSX components@react-three/drei
– useful helpers for react-three-fiber@react-three/postprocessing
– post-processing effects@react-three/flex
– flexbox for react-three-fiber@react-three/xr
– VR/AR controllers and events@react-three/cannon
– physics based hooks@react-three/a11y
– real a11y for your scenezustand
– state managementreact-spring
– a spring-physics-based animation libraryreact-use-gesture
– mouse/touch gesturesleva
– create GUI controls in secondsIf you like this project, please consider helping out. All contributions are welcome as well as donations to Opencollective, or in crypto BTC: 36fuguTPxGCNnYZSRdgdh6Ea94brCAjMbH
, ETH: 0x6E3f79Ea1d0dcedeb33D3fC6c34d2B1f156F2682
.
Thank you to all our backers! 🙏
This project exists thanks to all the people who contribute.
FAQs
A React renderer for Threejs
The npm package @react-three/fiber receives a total of 354,173 weekly downloads. As such, @react-three/fiber popularity was classified as popular.
We found that @react-three/fiber demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 22 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.