|
@@ -3,7 +3,7 @@ import * as THREE from "three"
|
|
|
import FbxFile from '../../../assets/3d/head-mast.fbx'
|
|
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
|
|
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
|
|
|
-import button from "../../../compontens/button/sendcode";
|
|
|
+import { HEADMAST_TYPE } from '../../../contants'
|
|
|
|
|
|
const createCanvasText = (text, color = '#ffffff') => {
|
|
|
const canvas = document.createElement('canvas')
|
|
@@ -14,40 +14,98 @@ const createCanvasText = (text, color = '#ffffff') => {
|
|
|
return canvas
|
|
|
}
|
|
|
|
|
|
-const ThreeComponent = () => {
|
|
|
- const [modelPosition, setModelPosition] = React.useState({ x: -200,y: -115,z: 320 })
|
|
|
- const [loadProcess, setLoadProcess] = React.useState('0%')
|
|
|
- React.useEffect(() => {
|
|
|
- const rootEle:any = document.getElementById('three-box')
|
|
|
- const scene = new THREE.Scene()
|
|
|
- const camera = new THREE.PerspectiveCamera(50, rootEle.clientWidth / rootEle.clientHeight, 1, 2000)
|
|
|
- // default xyz
|
|
|
- const { x, y, z } = modelPosition
|
|
|
- camera.position.set(x, y, z)
|
|
|
- // const helper = new THREE.CameraHelper( camera )
|
|
|
- // scene.add( helper )
|
|
|
- // 迪迦
|
|
|
- const hemisphereLight = new THREE.AmbientLight(0xffffff, 1)
|
|
|
- // hemisphereLight.position.set(0, 50, 60);
|
|
|
- scene.add(hemisphereLight)
|
|
|
+const initThree:any = (spriteList: Array<any> = [], rootEle, setLoadProcess) => {
|
|
|
+ // const renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
|
|
|
+ // 已经存在场景
|
|
|
+ if (initThree.scene) {
|
|
|
+ initThree.scene.children = initThree.scene.children.filter(item => {
|
|
|
+ return ['AmbientLight', 'Group'].includes(item.type)
|
|
|
+ })
|
|
|
+ // reload
|
|
|
+ AddSpriteList(initThree.scene, spriteList)
|
|
|
+ initThree.renderer.render(initThree.scene, initThree.camera);
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // cache
|
|
|
+ initThree.scene = new THREE.Scene()
|
|
|
+ initThree.camera = new THREE.PerspectiveCamera(50, rootEle.clientWidth / rootEle.clientHeight, 1, 2000)
|
|
|
+ initThree.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
|
|
|
+
|
|
|
+ const { scene, camera, renderer } = initThree
|
|
|
+ // const scene = new THREE.Scene()
|
|
|
+ // const camera = new THREE.PerspectiveCamera(50, rootEle.clientWidth / rootEle.clientHeight, 1, 2000)
|
|
|
|
|
|
- const renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
|
|
|
- renderer.setClearColor(0x000000, 0);
|
|
|
+ // default xyz
|
|
|
+ const [x, y, z] = [-200, -115, 320]
|
|
|
+ camera.position.set(x, y, z)
|
|
|
+ // const helper = new THREE.CameraHelper( camera )
|
|
|
+ // scene.add( helper )
|
|
|
+ // 迪迦
|
|
|
+ const hemisphereLight = new THREE.AmbientLight(0xffffff, 1)
|
|
|
+ // hemisphereLight.position.set(0, 50, 60);
|
|
|
+ scene.add(hemisphereLight)
|
|
|
+
|
|
|
+ renderer.setClearColor(0x000000, 0);
|
|
|
+ if (rootEle.childNodes[0]) {
|
|
|
+ rootEle.replaceChild(renderer.domElement, rootEle.childNodes[0])
|
|
|
+ } else {
|
|
|
rootEle.appendChild(renderer.domElement)
|
|
|
- renderer.setSize(rootEle.clientWidth, rootEle.clientHeight);
|
|
|
+ }
|
|
|
+ renderer.setSize(rootEle.clientWidth, rootEle.clientHeight);
|
|
|
+ // 加载fbx
|
|
|
+ const loader = new FBXLoader()
|
|
|
+ loader.load(FbxFile, (fbx) => {
|
|
|
+ // const axesHelper = new THREE.AxesHelper( 200 );
|
|
|
+ // scene.add( axesHelper );
|
|
|
+ fbx.scale.set(0.05, 0.05, 0.05)
|
|
|
+ scene.add(fbx)
|
|
|
+ renderer.render(scene, camera)
|
|
|
+ console.log(scene)
|
|
|
+ }, ({loaded, total}) => {
|
|
|
+ const process:any = (loaded / total * 100).toFixed(2)
|
|
|
+ return setLoadProcess(process)
|
|
|
+ })
|
|
|
+ AddSpriteList(scene, spriteList)
|
|
|
+ // renderer.render(scene, camera)
|
|
|
+ // add camera controller
|
|
|
+ const controls = new OrbitControls(camera, renderer.domElement);
|
|
|
+ controls.addEventListener("change", () => {
|
|
|
renderer.render(scene, camera);
|
|
|
- // 加载fbx
|
|
|
- const loader = new FBXLoader()
|
|
|
- loader.load(FbxFile, (fbx) => {
|
|
|
- // const axesHelper = new THREE.AxesHelper( 200 );
|
|
|
- // scene.add( axesHelper );
|
|
|
- fbx.scale.set(0.05, 0.05, 0.05)
|
|
|
- scene.add(fbx)
|
|
|
- renderer.render(scene, camera)
|
|
|
- }, ({loaded, total}) => {
|
|
|
- setLoadProcess(`${(loaded / total * 100).toFixed(2)}%`)
|
|
|
- })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const AddSpriteList = (scene, spriteList) => {
|
|
|
+ spriteList.forEach((info, index) => {
|
|
|
+ const texture = new THREE.Texture(createCanvasText(info.text))
|
|
|
+ texture.needsUpdate = true
|
|
|
+ const spriteMaterial = new THREE.SpriteMaterial({map: texture})
|
|
|
+ const sprite = new THREE.Sprite(spriteMaterial)
|
|
|
+ sprite.scale.set(60, 30, 1)
|
|
|
+ sprite.position.set(info.position[0], info.position[1], info.position[2])
|
|
|
+ scene.add(sprite)
|
|
|
+ // create 3d object line
|
|
|
+ const lineMaterial = new THREE.LineBasicMaterial({color: 0xffffff})
|
|
|
+ const geometry = new THREE.BufferGeometry().setFromPoints(info.points)
|
|
|
+ const line = new THREE.Line(geometry, lineMaterial)
|
|
|
+ line.scale.set(4, 4, 1)
|
|
|
+ line.position.set(info.line[0], info.line[1], info.line[2])
|
|
|
+ scene.add(line)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+interface ThreeComponentProps {
|
|
|
+ baseData: any
|
|
|
+}
|
|
|
+
|
|
|
+const ThreeComponent: React.FC<ThreeComponentProps> = (props) => {
|
|
|
+ const [modelPosition, setModelPosition] = React.useState({ x: -200,y: -115,z: 320 })
|
|
|
+ const [loadProcess, setLoadProcess] = React.useState(0)
|
|
|
+
|
|
|
+ const rootEle:any = document.getElementById('three-box')
|
|
|
|
|
|
+ React.useEffect(() => {
|
|
|
+ const textArr = ['塔臂高', '后臂长', '前臂长', '塔帽高']
|
|
|
+ if (!props.baseData.base) return
|
|
|
const spriteList = [
|
|
|
{
|
|
|
text: 'Block_信息展示1',
|
|
@@ -85,41 +143,30 @@ const ThreeComponent = () => {
|
|
|
new THREE.Vector3(0, 0, 30)
|
|
|
]
|
|
|
}
|
|
|
- ]
|
|
|
- spriteList.forEach((info, index) => {
|
|
|
- const texture = new THREE.Texture(createCanvasText(info.text))
|
|
|
- texture.needsUpdate = true
|
|
|
- const spriteMaterial = new THREE.SpriteMaterial({map: texture})
|
|
|
- const sprite = new THREE.Sprite(spriteMaterial)
|
|
|
- sprite.scale.set(60, 30, 1)
|
|
|
- sprite.position.set(info.position[0], info.position[1], info.position[2])
|
|
|
- scene.add(sprite)
|
|
|
- // create 3d object line
|
|
|
- const lineMaterial = new THREE.LineBasicMaterial({color: 0xffffff})
|
|
|
- const geometry = new THREE.BufferGeometry().setFromPoints(info.points)
|
|
|
- const line = new THREE.Line(geometry, lineMaterial)
|
|
|
- line.scale.set(4, 4, 1)
|
|
|
- line.position.set(info.line[0], info.line[1], info.line[2])
|
|
|
- scene.add(line)
|
|
|
- })
|
|
|
- // add camera controller
|
|
|
- const controls = new OrbitControls(camera, renderer.domElement);
|
|
|
- controls.addEventListener("change", () => {
|
|
|
- renderer.render(scene, camera);
|
|
|
- const { x, y ,z } = camera.position
|
|
|
- setModelPosition({
|
|
|
- x, y, z
|
|
|
- })
|
|
|
+ ].map((item, index) => {
|
|
|
+ const key = Object.keys(props.baseData.base)[index]
|
|
|
+ item.text = `${textArr[index]}:${(props.baseData.base[key])}`
|
|
|
+ return item
|
|
|
})
|
|
|
- }, [])
|
|
|
+ initThree(spriteList, rootEle, setLoadProcess)
|
|
|
+ }, [props.baseData.base])
|
|
|
|
|
|
- return <div>
|
|
|
- { loadProcess !== '100.00%' && loadProcess }
|
|
|
+ const LoadComponent = () => (
|
|
|
+ <div className='load-process'>
|
|
|
+ <div className='load-process-bar'>
|
|
|
+ <div className='bar' style={{
|
|
|
+ transform: `translate(${loadProcess}%, 0)`
|
|
|
+ }}/>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ return <React.Fragment>
|
|
|
+ { (loadProcess < 100) && LoadComponent() }
|
|
|
{/*<div>*/}
|
|
|
{/* x: { modelPosition.x } y: { modelPosition.y } z: { modelPosition.z }*/}
|
|
|
{/*</div>*/}
|
|
|
<div id="three-box"/>
|
|
|
- </div>
|
|
|
+ </React.Fragment>
|
|
|
}
|
|
|
|
|
|
-export default ThreeComponent
|
|
|
+export default ThreeComponent
|