Skip to content

Three Object

Example

Example Source Code
tsx
import React, { useCallback, useEffect, useRef, useState } from 'react'
import ReactDOM from 'react-dom'
import * as THREE from 'three'
import { MbMap, MbTiandituLayer } from '@mapbox-react/core'

const App = () => {
  const [mapCenter] = useState([116.3466, 39.8704])
  const [zoom, setZoom] = useState(15)
  const [pitch, setPitch] = useState(45)
  const mapInst = useRef<any>()

  let map: any
  const altitude = 0

  const mapCreated = (mapbox: any) => {
    map = mapbox
  }
  const add3DLayer = () => {
    loaderModels()
  }
  const loaderModels = () => {
    const geometry = new THREE.PlaneGeometry(300, 300)
    const material = new THREE.MeshBasicMaterial({
      map: new THREE.TextureLoader().load(
        `https://mapbox-web.github.io/mapbox-react/images/firefox.png`
      ),
      transparent: true,
      // color: 0xffff00,
      side: THREE.DoubleSide,
    })
    const plane = new THREE.Mesh(geometry, material)
    plane.rotation.x = -Math.PI / 2
    plane.name = 'plane'

    const cube = new THREE.Mesh(
      new THREE.BoxGeometry(300, 300, 300),
      new THREE.MeshNormalMaterial()
    )
    cube.name = 'cube'

    const cube1 = cube.clone()
    cube1.material = new THREE.MeshNormalMaterial()
    cube1.name = 'cube1'

    addThreeLayer(plane, cube, cube1)
  }
  const addThreeLayer = (plane, cube, cube1) => {
    const threeLayer = new map.mapboxgl.supermap.ThreeLayer('threeLayer')
    threeLayer.on('initialized', render)

    let light
    function render() {
      const renderer = threeLayer.getThreeRenderer(),
        scene = threeLayer.getScene(),
        camera = threeLayer.getCamera()
      // scene.background = new THREE.Color('skyblue')
      light = new THREE.PointLight(0xffffff, 0.8)
      light.position.copy(camera.position)
      scene.add(light)
      scene.add(new THREE.AmbientLight(0xffffff))

      threeLayer.setPosition(plane, mapCenter)
      threeLayer.setPosition(cube, mapCenter)
      threeLayer.setPosition(cube1, mapCenter)

      plane.translateY(340)
      cube.translateX(800)
      scene.add(plane)
      scene.add(cube)
      scene.add(cube1)

      renderer.render(scene, camera)
    }

    // 均匀光照,与相机位置同步
    // Even lighting, synchronized with camera position
    threeLayer.on('render', () => {
      light && light.position.copy(threeLayer.renderer.camera.position)
    })
    map.addLayer(threeLayer)
  }

  return (
    <div className="map-wrapper">
      <MbMap
        ref={mapInst}
        center={mapCenter}
        zoom={zoom}
        pitch={pitch}
        onCreated={mapCreated}
      >
        <MbTiandituLayer types={['vec', 'cva']} onCreated={add3DLayer} />
      </MbMap>
    </div>
  )
}

ReactDOM.render(<App />, document.querySelector('#root'))