用组件的方式开发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.css
body {
/* 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'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 scene
const container = document.querySelector('#scene-container');
// create a Scene
const scene = new Scene();
// Set the background color
scene.background = new Color('skyblue');
// Create a camera
const fov = 35; // AKA Field of View
const aspect = container.clientWidth / container.clientHeight;
const near = 0.1; // the near clipping plane
const 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 scene
camera.position.set(0, 0, 10);
// create a geometry
const geometry = new BoxBufferGeometry(2, 2, 2);
// create a default (white) Basic material
const material = new MeshBasicMaterial();
// create a Mesh containing the geometry and material
const cube = new Mesh(geometry, material);
// add the mesh to the scene
scene.add(cube);
// create the renderer
const renderer = new WebGLRenderer();
// next, set the renderer to the same size as our container element
renderer.setSize(container.clientWidth, container.clientHeight);
// finally, set the pixel ratio so that our scene will look good on HiDPI displays
renderer.setPixelRatio(window.devicePixelRatio);
// add the automatically created <canvas> element to the page
container.append(renderer.domElement);
// render, or 'create a still image', of the scene
renderer.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 };