Skip to content

利用 GLTFLoader 加载器查看模型的加载进度

js
loader.load(模型路径, 加载完成函数, 加载过程函数);

模型本身是有大小的,通过浏览器从服务器加载的时候,本身网络传输是需要时间的

.load()方法的参数 2 是一个函数,参数 2 函数是在模型加载完成之后才会被调用执行

.load()方法的参数 3 是一个函数,通过函数的参数获取模型加载信息,每当模型加载部分内容,该函数就会被调用,一次加载过程中一般会被调用多次,直到模型加载完成

js
loader.load(
  '../工厂.glb',
  function (gltf) {
    model.add(gltf.scene);
  },
  function (xhr) {
    // 控制台查看加载进度xhr
    // 通过加载进度可以控制前端进度条进度
    const percent = xhr.loaded / xhr.total;
    console.log('加载进度' + percent);
  }
);

利用回调函数的参数控制进度条

js
loader.load(
  '../工厂.glb',
  function (gltf) {
    model.add(gltf.scene);
  },
  function (xhr) {
    const percent = xhr.loaded / xhr.total;
    // console.log('加载进度' + percent);
    percentDiv.style.width = percent * 400 + 'px'; //进度条元素长度
    percentDiv.style.textIndent = percent * 400 + 5 + 'px'; //缩进元素中的首行文本
    // Math.floor:小数加载进度取整
    percentDiv.innerHTML = Math.floor(percent * 100) + '%'; //进度百分比
  }
);

加载完成后隐藏进度条

threejs 模型加载完成后,就不需要显示进度条,可以通过.style.display 属性设置,也可以通过.style.visibility 属性隐藏进度条

js
loader.load(
  '../工厂.glb',
  function (gltf) {
    model.add(gltf.scene);
    // 加载完成后隐藏进度条
    // document.getElementById("container").style.visibility ='hidden';
    document.getElementById('container').style.display = 'none';
  },
  function (xhr) {
    const percent = xhr.loaded / xhr.total;
    console.log('加载进度' + percent);
  }
);

完整代码

index.html

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="loader-container">
      <div id="loader"></div>
    </div>

    <script type="importmap">
      {
        "imports": {
          "three": "../../build/three.module.js",
          "three/addons/": "../../examples/jsm/"
        }
      }
    </script>

    <script src="./index.js" type="module"></script>
  </body>
</html>

<style>
  * {
    margin: 0;
    padding: 0;
  }

  #loader-container {
    position: absolute;
    top: 50%;
    bottom: 0;
    right: 0;
    left: 0;
    width: 400px;
    height: 30px;
    margin: 0 auto;
    background-color: black;
    border-radius: 20px;
  }
  #loader {
    width: 0;
    height: 100%;
    color: #fff;
    line-height: 30px;
    background-color: aquamarine;
    border-radius: 20px;
  }
</style>

index.js

js
import * as THREE from 'three';
import { group } from './model.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const width = window.innerWidth;
const height = window.innerHeight;

const scene = new THREE.Scene();
scene.add(group);

const camera = new THREE.PerspectiveCamera(30, width / height, 0.1, 1000);
camera.position.set(100, 100, 100);

const ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);

const render = () => {
  renderer.render(scene, camera);
  window.requestAnimationFrame(render);
};

render();

new OrbitControls(camera, renderer.domElement);
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);

document.body.appendChild(renderer.domElement);

window.onresize = () => {
  const width = window.innerWidth;
  const height = window.innerHeight;
  renderer.setSize(width, height);
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
};

model.js

js
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const group = new THREE.Group();
const loader = new GLTFLoader();

loader.load(
  './工厂.gltf',
  (gltf) => {
    group.add(gltf.scene);
    document.getElementById('loader-container').style.display = 'none';
  },
  (xhr) => {
    // .total: 总字节数
    // .loaded: 已加载的字节数
    const percent = xhr.loaded / xhr.total;
    const loaderDiv = document.getElementById('loader');

    loaderDiv.style.width = percent * 400 + 'px';
    loaderDiv.style.textIndent = percent * 400 + 5 + 'px'; //缩进元素中的首行文本
    loaderDiv.innerHTML = Math.floor(percent * 100) + '%';
  }
);

export { group };

效果

上次更新于: