用组件的方式开发threejs多个模型动画网页
偶尔的机会,阅读完https://discoverthreejs.com/ 这个网站的所有内容,对threejs组织结构有了新的认识。这样也极大地方便之后用在vuejs项目中。下面是它的组织结构。
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:}h1 {/* position the heading */position: absolute;width: 100%;/* make sure that the heading is drawn on top */z-index: 1;}/* 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'sbackground 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 planeconst 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);
只有立方体时候的文件结构:
增加贴图后:
增加分组:
多模型的处理方式:
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 };
