3D front-end document

1. Overall flow chart

2. Implementation steps
  1. Creating a local database

     connect.onupgradeneeded = function (event) {
          console.log("Database Update")
          db = event.target.result;
          // Check whether the table exists
          if(! db.objectStoreNames.contains('person')) {
            / / create a table
            var objectStore;
            objectStore = db.createObjectStore('person', {
              / / the primary key
              keyPath: 'id'
            });
            // Create index
            objectStore.createIndex('blob'.'blob', {
              // Is it unique
              unique: false
            });
            objectStore.createIndex('name'.'name', {
              // Is it unique
              unique: true}); }}Copy the code
  2. Find the local model

function find(storename, key, callback) {
      let store = db.transaction(storename, 'readwrite').objectStore(storename);
      let request = store.get(key);
      request.onerror = function () {
        console.error('getDataByKey error');
      };
      request.onsuccess = function (e) {
        The / / check
        if (result) {
          var url = URL.createObjectURL(result.blob)
          THREE.DRACOLoader.setDecoderPath('three/examples/js/libs/draco/gltf/'); // Set the path to the decompressed library file
          var dracoLoader = new THREE.DRACOLoader();
          gltfloader.setDRACOLoader(dracoLoader);
          gltfloader.load(url, function (gltf) {
            // Clear the BLOB protocol cache
            // URL.revokeObjectURL(url)
            scene.add(gltf.scene)
            setCameraHide(false);
            addCameraImg()
            gltf.scene.position.set(-5.0.0);
            setTimeout(() = > {
              renderDailog();
              console.log('Render done'.new Date());

            }, 10)
            if(callback) { callback(result); }}); }else {
          console.log('No trace');
          console.log('Start downloading'.new Date()); xhr.send(); }}}Copy the code
  1. Download the model
 var xhr = new XMLHttpRequest(),
      blob;

    xhr.open("GET", url, true);
    // Set the responseType to blob
    xhr.responseType = "blob";
    xhr.addEventListener("load".function () {
      if (xhr.status === 200) {
        console.log('Download completed'.new Date());
        // File as response
        blob = xhr.response;
        addData('person', {
          id: 'parkwh'.blob: blob
        }, () = > {
          console.log('Added successfully - Query started')
          find('person'.'parkwh'.() = > {
            console.log('End of search')})})// Put the received blob into IndexedDB
        // putElephantInDb(blob);}},false);
Copy the code
  1. Add indexDb
function addData(storename, data, callback) {
      let store = db.transaction(storename, 'readwrite').objectStore(storename);
      let request = store.add(data);
      request.onerror = function () {
        console.error('add adds the data to the database already ')}; request.onsuccess =function () {
        console.log('add add data to database ')
        callback();
      };
    }
Copy the code
  1. GltfLoader loads the model, adds the model to the scene, and sets the initial position of the model
 var url = URL.createObjectURL(result.blob)
          // let loader = new THREE.GLTFLoader();
          THREE.DRACOLoader.setDecoderPath('three/examples/js/libs/draco/gltf/'); // Set the path to the decompressed library file
          var dracoLoader = new THREE.DRACOLoader();
          gltfloader.setDRACOLoader(dracoLoader);
          gltfloader.load(url, function (gltf) {
            // Clear the BLOB protocol cache
            // URL.revokeObjectURL(url)
            scene.add(gltf.scene)
            setCameraHide(false);
            addCameraImg()
            gltf.scene.position.set(-5.0.0);
            setTimeout(() = > {
              renderDailog();
              console.log('Render done'.new Date());

            }, 10)
            if(callback) { callback(result); }}); }Copy the code
  1. Notify the main program of point coordinates
const renderDailog = () = > {
    let ad = [];
    if(! scene)return null;
    const arr = scene.children.find((d) = > d.type === 'Scene');
    const text = arr.children.find((d) = > d.name === "warning");

    const dataS = [];
    if (text && text.children) {
        text.children.map((li) = > {
            li.getWorldPosition(worldVector);
            // In special cases, local coordinates are equal to world coordinates
            // var worldVector = boxMesh.position.clone();
            // standardVector is WebGL standard-device
            //.project() extracts the view matrix and projection matrix of camera parameters to transform the world coordinates
            const standardVector = worldVector.project(camera);
            const a = width / 2;
            const b = height / 2;
            const x = Math.round(standardVector.x * a + a); // Model label x coordinates in pixels
            const y = Math.round(-standardVector.y * b + b); // Model label y coordinates in pixels
            li.domTop = y;
            li.domLeft = x;
            dataS.push({
                name: li.name.replace('dw-'.' ').replace('dw_'.' '),
                domTop: li.domTop,
                domLeft: li.domLeft,
            });

        });
    }

    sendMessage('dailog', dataS);
};
    
const sendMessage = (title, obj) = > {
    var data = {
        name: title,
        data: obj,
    };
    window.parent.postMessage(data, The '*'); //window.postMessage
};
Copy the code
  1. Camera hiding

    const setCameraHide = (bool) = > {

      if(! scene)return;
      const sce = scene.children.find(d= > d.type === "Scene")
      if(! sce)return;
      const obj = sce.children.find(d= > d.name === "cameras")
      if(! obj)return;
      if (bool) {
        obj.children.map((d) = > {
          if (bool.data[d.name.replace('sxt_'.' ').replace('sxt-'.' ')]) { d.children? .map((li) = > {
              li.visible = true; })}})}else {
        obj.children.map((d) = >{ d.children? .map((li) = >{ li.visible = bool; }}})})Copy the code
  1. Entrance to hide
const addCameraImg = () = > {

      if(! scene)return;
      const sce = scene.children.find(d= > d.type === "Scene")
      console.log(sce, The '-')
      if(! sce)return;
      const cameras = sce.children.find(d= > d.name === "cameras")
      if(! cameras)return;
      const warnings = sce.children.find(d= > d.name === "warning")
      const titles = sce.children.find(d= > d.name === "Text") warnings? .children.map((d) = > {
        d.material.visible = false; }) titles? .children.map((d) = > {
        // d.material.visible = false;d.children? .map((li) = > {
          li.material.visible = false;
        })

        setTitle(d)
      })
      console.log(cameraData, 'cameraData') cameras? .children.map((d) = > {
        d.material.visible = false; setLabel(d); }) cameras? .children.map((d) = >{ d.children? .map((li) = > {
          li.visible = false; })})}Copy the code
  1. Custom camera/entrance
const setLabel = (onjectValue) = > {
    var labelDiv = document.createElement('div')
    labelDiv.className = 'label';
    labelDiv.name = onjectValue.name;
    labelDiv.ondblclick = cameraClick;
    var earthLabel = new THREE.CSS2DObject(labelDiv)
    onjectValue.add(earthLabel)
}
const setTitle = (onjectValue) = > {
    const arr =
          [
              {
                  code: 'fftl'.name: 'Float desulphurization'
              },
              {
                  code: "cc1".name: 'warehouse 1'
              },
              {
                  code: "cc2".name: 'warehouse 2'
              },
              {
                  code: "dd500".name: 'electronic 500 t'
              },
              {
                  code: "dmrx".name: 'Coated two wire'
              },
              {
                  code: "dmsx".name: 'Coated three wire'
              },
              {
                  code: "dmyx".name: 'Coating line'
              },
              {
                  code: "dz200".name: 'electronic 200 t'
              },
              {
                  code: "dzcy".name: 'Electronic storage and transportation'
              },
              {
                  code: "dztltx".name: 'Electronic desulfurization and denitrification'
              },
              {
                  code: "ff500".name: 'float 500 t'
              },
              {
                  code: "ff600".name: 'float 600 t'
              },
              {
                  code: "ff700".name: 'float 700 t'
              },
              {
                  code: "ff900".name: 'float 900 t'
              },
              {
                  code: "trqzq".name: 'Hydrogen from natural gas'
              },
              {
                  code: "yqdqz".name: 'Primary nitrogen hydrogen station'
              },
              {
                  code: "dz".name: 'n stand'
              },
              {
                  code: "dztl".name: 'electronic desulfurization'
              },
              {
                  code: "dztx".name: 'Electronic denitration'},]const obj = arr.find((d) = > d.code === onjectValue.name)
    if (obj && obj.name) {
        var labelDiv = document.createElement('div')
        labelDiv.className = 'title';
        labelDiv.innerText = obj.name;
        labelDiv.id = obj.code;
        labelDiv.name = onjectValue.name;
        labelDiv.ondblclick = enterLine;
        var earthLabel = new THREE.CSS2DObject(labelDiv)
        onjectValue.add(earthLabel)
    }
}
Copy the code
  1. Set up light/camera/renderer
const setLight = () = > {
    / / the ambient light
    var ambient = new THREE.AmbientLight(0xC4C4C4.1);
    var point = new THREE.PointLight(0xC4C4C4.1);
    var point1 = new THREE.PointLight(0xC4C4C4.1);
    var point2 = new THREE.PointLight(0xC4C4C4.1);
    / / the point light source

    point.position.set(-15.432835578918457.37.574790954589844.77.27122497558594); // Point light source position
    point1.position.set(356.2715148925781.127.52357482910156, -142.99517822265625); // Point light source position
    point2.position.set(-54.23904037475586.28.659584045410156, -59.19256591796875); // Point light source position

    scene.add(point); // Add a light source to the scene
    scene.add(point1); // Add a light source to the scene
    scene.add(point2); // Add a light source to the scene
    / / the ambient light
    // scene.add(ambient);
};

/** * Camera Settings */
const setCamera = () = > {
    camera.position.set(11.582765074860337.80.84475536367229.154.73173390246936); // Set the camera position
    camera.lookAt(new THREE.Vector3(0.0.0)); // Set the camera orientation (the scene object to point to)
};

/** * Create the renderer object */
const setRender = () = > {
    renderer.shadowMap.enabled = false;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    renderer.setSize(width, height); // Set the render area size
    // renderer.setClearColor(0x000000, 1); // Set the background color
    document.body.appendChild(renderer.domElement); // Insert the canvas in the body element
    labelRenderer = new THREE.CSS2DRenderer();
    labelRenderer.setSize(width, height);
    labelRenderer.domElement.style.position = "absolute";
    labelRenderer.domElement.style.top = 0;
    document.body.appendChild(labelRenderer.domElement);
};
Copy the code
  1. Add double click events/row events
function dbclick(event) {
    if(! scene)return;
    if(! scene.children.find((d) = > d.type === 'Scene')) return;

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    raycaster.setFromCamera(mouse, camera);
    const arr = scene.children.find((d) = > d.type === 'Scene');
}

function mouseover(event) {
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    raycaster.setFromCamera(mouse, camera);
    const arr = scene.children.find((d) = > d.type === 'Scene');
    const text = arr.children.find((d) = > d.name === 'words');
    var intersects = raycaster.intersectObjects(text.children, true);
    if (intersects.length > 0) {
        selectObj && (selectObj.material.color = oldColor);
        selectObj = intersects[0].object;
        var{ r, g, b } = { ... selectObj.material.color }; oldColor =new THREE.Color(r, g, b);
        selectObj.material.color.set('#b97751');
        selectObj.material.needsUpdate = true;
    } else{ selectObj && (selectObj.material.color = oldColor); }}Copy the code