Add 3D model in React - javascript

I want to add a 3D avatar in my portfolio built with React. I followed this tutorial: React portfolio
In my header section, I want to replace my image with 3D avatar using three.js following this tutorial
Here is the Model.jsx file
import React, { useRef } from "react";
import { Canvas, extend, useThree, useFrame } from "react-three-fiber";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
extend({ OrbitControls });
function Model() {
const Controls = () => {
const controls = useRef();
const { camera, gl } = useThree();
useFrame(() => {
controls.current.update();
});
return (
<orbitControls
ref={controls}
autoRotate
args={[camera, gl.domElement]}
></orbitControls>
);
};
return (
<div>
<Canvas>
<mesh>
<Controls />
<boxBufferGeometry
attach="geometry"
args={[1, 1, 1]}
></boxBufferGeometry>
<meshBasicMaterial
wireframe
attach="material"
color="white"
></meshBasicMaterial>
</mesh>
</Canvas>
</div>
);
}
export default Model;
Here is my Header.jsx file
import React from 'react'
import './header.css'
import CTA from './CTA'
// import Me from '../../assets/me.jpg'
import HeaderSocials from './HeaderSocials'
import Model from './Model'
const Header = () => {
return (
<header id='header'>
<div className="container header_container">
<h5>
Hello I'm
</h5>
<h1>John Smith</h1>
<h5 className="text-light"> Full-stack Developer</h5>
<CTA />
<HeaderSocials />
{/* <div className="me">
<img src={Me} alt="" />
</div> */}
<Model />
Scroll Down
</div>
</header>
)
}
export default Header
I'm getting this error message:
Failed to compile.
Module not found: Error: Can't resolve 'react-three-fiber' in 'C:\Users\xxxxx\Desktop\Projects\react-portfolio\src\components\header'
ERROR in ./src/components/header/Model.jsx 5:0-71
Module not found: Error: Can't resolve 'react-three-fiber' in 'C:\Users\xxxxx\Desktop\Projects\react-portfolio\src\components\header'
webpack compiled with 1 error
Can anyone guide me on how to do it?

react-three-fiber is deprecated, you want to use #react-three/fiber instead and so you'd do npm install #react-three/fiber or yarn install #react-three/fiber. Then you'd have to update your imports like:
import { Canvas, extend, useThree, useFrame } from "#react-three/fiber";
Furthermore, if you want to use OrbitControls, the #react-three/drei package has them built in as a JSX element, simply import it and do <OrbitControls />, more information in their GitHub page.
One last advice is that you should wrap your Model inside a <Suspense> tag, this is new in React 18 so make sure your react and react-dom packages are up to date and in-sync.

Related

Unable to view Model with OBJLoader React Three Fiber

I'm trying to render an .obj file into my react project using the OBJLoader and useLoader() hook from React Three Fiber, but I'm unable to do so. My file path is correct and I'm wrapping the Model in Suspense tags, so why is this occurring?
import React, { Suspense } from "react";
import * as THREE from "three";
import { Canvas, useLoader } from "#react-three/fiber";
import { OrbitControls } from "#react-three/drei";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
function Model() {
const model = useLoader(
OBJLoader,
"../assets/Model.obj"
);
return <primitive object={model} scale={0.4} />;
}
function App() {
return (
<div className="App">
<Canvas>
<OrbitControls
enablePan={true}
enableZoom={true}
enableRotate={true}
addEventListener={undefined}
hasEventListener={undefined}
removeEventListener={undefined}
dispatchEvent={undefined}
/>
<Lights />
<Suspense fallback={null}>
<Model />
</Suspense>
</Canvas>
</div>
);
}
export default App;
You have to put your 3D files inside the public folder.
Then your path will be "./Model.obj"
Also you can make make folders inside public folder and put 3D models inside them.
ex- "./folder1/Model.obj" like this

React-create-library Import Image Issue

I am creating new project using create-react-library but when I tried to import image using import logo from './logo.png', the image does not show up in the example, but if I use import logo from 'logo.png' the image show up.
My question is this normally happen?
here is the folder structure of my project
not working version
result
code:
import React from 'react'
import styles from './styles.module.css'
import logo from './logo.png'
export const ExampleComponent = ({ text }) => {
return (
<div className={styles.test}>
{/* Example Component: {text} */}
<img src={logo} />
</div>
)
}
working version
result
code:
import React from 'react'
import styles from './styles.module.css'
import logo from 'logo.png'
export const ExampleComponent = ({ text }) => {
return (
<div className={styles.test}>
{/* Example Component: {text} */}
<img src={logo} />
</div>
)
}
Hi I am also new with react-create-library and was having the same problem. My image was in the folder src/assets/img and when I was trying to add the path relatively it was failing.
What i found is path should be after the ./src/ folder.
following is the code that worked for me for the icon in src/assets/img folder.
import * as React from 'react';
import styles from './styles.module.css';
import warnicon from 'assets/img/warning.png';
.
.
.
<div className={styles.modalBody}>
<img src={warnicon} alt='warn-icon'></img>
<p className={styles.warning}>{props.text}</p>
</div>
Thank you.
yes it is normally the way it happens. Although adding your code would have helped but I have added an example:-
import React from 'react';
import logo from './logo.png';
console.log(logo); // /logo.84287d09.png
function Header() {
// Import result is the URL of your image
return <img src={logo} alt="Logo" />;
}

Module not found: Can't resolve - React

I'm having a problem with the relative path for my react app. It seems super simple but I've double checked everything and I still can't get it to work.
The path is src > components(folder) > Navigation(folder) > navigation.js
The terminal says: "Failed to compile.
./src/App.js
Module not found: Can't resolve './components/Navigation/navigation' in '/Users/misbahhemraj/Desktop/facefind/src'"
This is my code in my app.Js:
import React, { Component } from 'react';
import navigation from './components/Navigation/navigation';
import './App.css';
class App extends Component {
render () {
return (
<div className="App">
<navigation />
{/*<Logo />
<ImageLinkForm />
<FaceRecognition />*/}
</div>
);
}
}
export default App;
This is my code in navigation.js
import React from 'react';
const Navigation = () => {
return (
<nav>
<p> Sign Out </p>
</nav>
)
}
export default navigation;
I've tried changing the ports and changing the syntax of the import statement but I can't get it it work. Any advice would be appreciated - thank you so much!
Look at your export component name, you have navigation and your component name it´s Navigation
import React from 'react';
const Navigation = () => {
return (
<nav>
<p> Sign Out </p>
</nav>
)
}
export default Navigation;

Additional component in <MuiThemeProvider /> results in blank page w/ no error messages

I have recently installed Material UI into my Meteor application using npm install --save material ui
I have gotten the <Header /> component showing up in my app.js file, but whenever I add other components, localhost:3000 simply displays a blank page. Please see my code below:
header.js
import React, { Component } from 'react';
import AppBar from 'material-ui/AppBar';
class Header extends Component {
render() {
return(
<AppBar
title="Header"
titleStyle={{textAlign: "center"}}
showMenuIconButton={false}
/>
);
}
}
export default Header;
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Header from './components/header';
import NewPost from './components/new_post';
const App = () => {
return (
<MuiThemeProvider>
<Header />
</MuiThemeProvider>
);
};
Meteor.startup(() => {
ReactDOM.render(<App />, document.querySelector('.render-target'));
});
THE ABOVE CODE WORKS WELL (see screenshot below)
However, if I add another component I get a blank screen
header.js is the same
new_post.js
import React, { Component } from 'react';
import TextField from 'material-ui/TextField';
class NewPost extends Component {
render() {
return (
<TextField
hintText="Full width"
fullWidth={true}
/>
);
}
}
export default NewPost;
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Header from './components/header';
import NewPost from './components/new_post';
const App = () => {
return (
<MuiThemeProvider>
<Header />
<NewPost />
</MuiThemeProvider>
);
};
Meteor.startup(() => {
ReactDOM.render(<App />, document.querySelector('.render-target'));
});
The result is simply a blank screen
Why does adding one more component (<NewPost />)inside of <MuiThemeProvider> result in a blank screen? I referred to the material-ui documentation and their sample projects but their application structure is not similar to mine. Any advice? Please let me know if you need more info to make this question clearer.
Wow very strange but I managed to get it working by simply adding a <div>
app.js
const App = () => {
return (
<MuiThemeProvider muiTheme={getMuiTheme()}>
<div>
<Header />
<NewPost />
</div>
</MuiThemeProvider>
);
}
Meteor.startup(() => {
ReactDOM.render(<App />, document.querySelector('.render-target'));
});
I would really appreciate if anyone could explain why adding a div makes this all work. Thank you!
I would really appreciate if anyone could explain why adding a div
makes this all work
If you look at the browser warning, "Invalid prop children of type array supplied to MuiThemeProvider, expected a single ReactElement.".
So, when you add a <div/> around your components, it wraps them together and turns them into a single react element.
MuiThemeProvider renders as null so you have to wrap children do anything - for example React.Fragment

Alt "connectToStores" deprecated in React/Flux App?

I am building a small chat app with React and Flux via a tutorial, however the tutorial seems to be out of date as it is using a method from Alt (used with Flux) that throws the following error:
Cannot resolve module 'alt/utils/connectToStores'
...which I believe is coming from the line with #connectToStores. Below is my code. I looked into this issue and it seems like Alt was broken up into smaller packages, one of them being Alt-React (which is stumping me completely). My question is, how can I use this method in an up-to-date manner?
import React from 'react';
import mui from 'material-ui';
import MessageList from './MessageList.jsx';
import MessageBox from './MessageBox.jsx';
import Login from './Login.jsx';
import ChannelList from './ChannelList.jsx';
import connectToStores from 'alt/utils/connectToStores';
import ChatStore from '../stores/ChatStore';
// Material UI
import * as Colors from 'material-ui/lib/styles/colors';
import AppBar from 'material-ui/lib/app-bar';
import getMuiTheme from 'material-ui/lib/styles/getMuiTheme';
#connectToStores // es7 decorator with deprecated 'connectToStores'
class App extends React.Component {
constructor() {
super();
}
static getStores() {
return [ChatStore];
}
static getPropsFromStores() {
return ChatStore.getState();
}
static childContextTypes = {
muiTheme: React.PropTypes.object
}
getChildContext() {
return {
muiTheme: getMuiTheme({
primary1Color: Colors.blue500,
primary2Color: Colors.blue700,
primary3Color: Colors.blue100,
accent1Color: Colors.pink400
})
};
}
render() {
var view = <Login />;
if (this.props.user) {
view = (
<div>
<div id="content-container">
<ChannelList />
<MessageList />
</div>
<MessageBox />
</div>
);
}
return (
<div>
<AppBar title="Chat App"/>
{{view}}
</div>
);
}
}
export default App;
The Alt Utils libraries have all been moved into a separate package at https://github.com/altjs/utils
Once installed
npm i --save-dev alt-utils
You can access the same libraries as the tutorial requires using:
import connectToStores from 'alt-utils/lib/connectToStores';
import {decorate, bind, datasource} from 'alt-utils/lib/decorators';

Categories