不能使用
umi
框架
使用nextjs
框架react-3d-viewer
需要判断使用
使用create-react-app
框架正常
3d模型在
public->modal
文件夹下
测试模型在这里下载:https://github.com/mrdoob/three.js/tree/master/examples/models
1.安装库
yarn add react-3d-viewer
yarn add three @types/three @react-three/fiber @types/three
yarn add @react-three/drei
2.使用react-3d-viewer
加载 obj、dea
格式的模型(加载gltf我本地无法显示)
示例:https://dwqdaiwenqi.github.io/react-3d-viewer/site/#/
<OBJModel
width="400" height="400"
position={{x:0,y:-100,z:0}}
src="/modal/female021.obj"
onLoad={()=>{
//...
}}
onProgress={(xhr:any)=>{
console.log('xhr===',xhr)
}}
/>
<DAEModel
src={'/modal/b.dae'}
onLoad={()=>{
// ...
}}
>
<DirectionLight color={'#fff'}/>
</DAEModel>
3. 使用react-three/fiber
加载obj、gld
格式的模型(其他类型的没测试)
import { Canvas } from "@react-three/fiber";
import { Environment, OrbitControls } from "@react-three/drei";
import { useLoader } from '@react-three/fiber'
//@ts-ignore
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import LittlestTokyoModal from './modals/LittlestTokyo'
function Scene() {
const obj = useLoader(OBJLoader, "/modal/female021.obj")
return <primitive object={obj} scale={0.02} />
}
<Canvas style={{
width:500,
height:500,
// marginTop:100,
// marginLeft:100,
background:'red'
}}>
{/* <ambientLight intensity={0.5} /> */}
{/* <directionalLight color={'#fff'} position={[0,0,5]} /> */}
{/* <pointLight color={'#fff'} position={[0,0,0]}/> */}
{/* <perspectiveCamera position={[0,0,5]} fov={60} near={0.1} far={1000}/> */}
<ambientLight />
{/* <pointLight position={[10, 10, 10]} /> */}
<mesh receiveShadow={false} castShadow={false}>
<Scene/>
</mesh>
<OrbitControls />
{/* <Environment preset="sunset" background /> */}
</Canvas>
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️(应该可以设置,但是我没找到......)
但是显示的效果不太好,中心点在图层的中心,手指滑动后显得很怪异
以这个模型为例: 手指上下滑动时,支点是脚部位置,而不是腰部的位置,脚部以下的内容无用
缩放也很怪异,模型显示区域只在上半层
加载glb
模型
1.cd到xxx.glb文件夹 (本人在 public->modal文件夹下)
2.执行 npx gltfjsx xxx.glb
3.会生成 xxx.jsx文件
4. xxx.jsx 转移到 src->modals文件夹下(本人处理)
// 引用
import LittlestTokyoModal from './modals/LittlestTokyo'
import React, { Suspense, useEffect, useRef, useState } from 'react';
import { Canvas } from "@react-three/fiber";
import { Environment, OrbitControls,useProgress,Html } from "@react-three/drei";
import LittlestTokyoModal from './modals/LittlestTokyo'
function App() {
const [show,setShow] = useState(false)
const [screenWidth,setScreenWidth] = useState(0)
useEffect(()=>{
setShow(true)
setScreenWidth(window.innerWidth)
},[])
return (
show?<Canvas style={{
width:screenWidth,
height:screenWidth,
background:'#fff'
}}>
<Suspense fallback={<Loader/>}>
<ambientLight intensity={0.5}/>
<directionalLight position={[-2,5,2]}/>
<OrbitControls/>
<LittlestTokyoModal scale={[0.008, 0.008, 0.01]}/>
</Suspense>
</Canvas> : <div>
loading。。。
</div>
)
}
// 模型加载中的组件
function Loader() {
const { active, progress, errors, item, loaded, total } = useProgress();
return <Html fullscreen>
<div style={{
color:'red',
display:'flex',
flexDirection:'row',
width:'100%',
background:'blue',
height:'100%',
justifyContent:'center',
alignItems:'center'
}}>
模型加载中:{progress.toFixed(2)} %
</div>
</Html>;
}