vlambda博客
学习文章列表

用组件的方式开发threejs多个模型动画网页

偶尔的机会,阅读完https://discoverthreejs.com/  这个网站的所有内容,对threejs组织结构有了新的认识。这样也极大地方便之后用在vuejs项目中。下面是它的组织结构。



html 的代码;

<!DOCTYPE html><html>
<head> <title>Discoverthreejs.com - The Structure of a three.js App</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="UTF-8" />
<link rel="icon" href="https://discoverthreejs.com/favicon.ico" type="image/x-icon">
<link href="./styles/main.css" rel="stylesheet" type="text/css">
<script type="module" src="./src/main.js"></script></head>
<body> <h1>Discoverthreejs.com - Nothing to see here yet :)</h1>
<div id="scene-container"> <!-- Our <canvas> will be inserted here --> </div></body>
</html>

css 代码:

styles/main.cssbody { /* remove margins and scroll bars */ margin: 0; overflow: hidden;
/* style text */ text-align: center; font-size: 12px; font-family: Sans-Serif;
/* color text */ color: #444;}
h1 { /* position the heading */ position: absolute; width: 100%;
/* make sure that the heading is drawn on top */ z-index: 1;}
#scene-container { /* tell our scene container to take up the full page */ position: absolute; width: 100%; height: 100%;
/* Set the container's background color to the same as the scene's background to prevent flashing on load */ background-color: skyblue;}

main.js代码:

import { BoxBufferGeometry, Color, Mesh, MeshBasicMaterial, PerspectiveCamera, Scene, WebGLRenderer,} from 'three';
// Get a reference to the container element that will hold our sceneconst container = document.querySelector('#scene-container');
// create a Sceneconst scene = new Scene();
// Set the background colorscene.background = new Color('skyblue');
// Create a cameraconst fov = 35; // AKA Field of Viewconst aspect = container.clientWidth / container.clientHeight;const near = 0.1; // the near clipping planeconst far = 100; // the far clipping plane
const camera = new PerspectiveCamera(fov, aspect, near, far);
// every object is initially created at ( 0, 0, 0 )// move the camera back so we can view the scenecamera.position.set(0, 0, 10);
// create a geometryconst geometry = new BoxBufferGeometry(2, 2, 2);
// create a default (white) Basic materialconst material = new MeshBasicMaterial();
// create a Mesh containing the geometry and materialconst cube = new Mesh(geometry, material);
// add the mesh to the scenescene.add(cube);
// create the rendererconst renderer = new WebGLRenderer();
// next, set the renderer to the same size as our container elementrenderer.setSize(container.clientWidth, container.clientHeight);
// finally, set the pixel ratio so that our scene will look good on HiDPI displaysrenderer.setPixelRatio(window.devicePixelRatio);
// add the automatically created <canvas> element to the pagecontainer.append(renderer.domElement);
// render, or 'create a still image', of the scenerenderer.render(scene, camera);

只有立方体时候的文件结构:

用组件的方式开发threejs多个模型动画网页


增加贴图后:

增加分组:



多模型的处理方式:

await Promise.all


setupModel.js代码:

function setupModel(data) { const model = data.scene.children[0];
return model;}
export { setupModel };

birds.js代码:

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { setupModel } from './setupModel.js';
async function loadBirds() { const loader = new GLTFLoader();
const [parrotData, flamingoData, storkData] = await Promise.all([ loader.loadAsync('/assets/models/Parrot.glb'), loader.loadAsync('/assets/models/Flamingo.glb'), loader.loadAsync('/assets/models/Stork.glb'), ]);
console.log('Squaaawk!', parrotData);
const parrot = setupModel(parrotData); parrot.position.set(0, 0, 2.5);
const flamingo = setupModel(flamingoData); flamingo.position.set(7.5, 0, -10);
const stork = setupModel(storkData); stork.position.set(0, -2.5, -10);
return { parrot, flamingo, stork, };}
export { loadBirds };