酷代码 AI
菜单
服务商

生日祝福粒子动画代码分析与改进

### 👍代码分析 这段代码是一个基于Three.js库实现的生日祝福粒子动画的HTML页面。它创建了一个包含粒子和文字的3D场景,并添加了轨道控制器以便用户可以交互。以下是代码的详细分析: #### 1. HTML结构和样式 ```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>生日祝福粒子动画</title> <style> body { margin: 0; overflow: hidden; background: #000; } canvas { display: block; } </style> </head> ``` - `<!DOCTYPE html>`:声明文档类型为HTML5。 - `<meta charset="UTF-8">`:设置字符编码为UTF - 8。 - 样式部分将`body`的边距设置为0,隐藏溢出内容,并将颜色设置为黑色。`canvas`元素设置为块级元素。 #### 2. Importmap ```html <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.160.0/build/three.module.js", "three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/" } } </script> ``` - 使用`importmap`来指定`three`库和其扩展的导入路径。 #### 3. JavaScript代码 ```javascript import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 初始化场景、相机、渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 轨道控制器,用于交互 const controls = new OrbitControls(camera, renderer.domElement); camera.position.z = 5; ``` - 导入`THREE`库和`OrbitControls`。 - 创建场景、透视相机和WebGL渲染器,并将渲染器的DOM元素添加到页面中。 - 创建轨道控制器,方便用户与场景交互,并设置相机的初始位置。 ```javascript // 粒子材质 const particleMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 0.05, transparent: true, depthTest: false, blending: THREE.AdditiveBlending }); // 生成粒子几何体 const particlesGeometry = new THREE.BufferGeometry(); const particlesCount = 10000; const posArray = new Float32Array(particlesCount * 3); for (let i = 0; i < particlesCount * 3; i++) { posArray[i] = (Math.random() - 0.5) * 10; } particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3)); // 粒子对象 const particlesMesh = new THREE.Points(particlesGeometry, particleMaterial); scene.add(particlesMesh); ``` - 创建粒子材质,设置颜色、大小、透明度等属性。 - 生成粒子几何体,随机生成粒子的位置,并将其添加到场景中。 ```javascript // 文字形状(这里以“生日快乐”为例,可根据需要修改) const textGeometry = new THREE.TextGeometry('生日快乐', { font: new THREE.FontLoader().parse({ family: 'Arial', style: 'normal', weight: 'normal', size: 1, stretch: 1, curves: [], bounds: new THREE.Box2(new THREE.Vector2(-0.5, -0.5), new THREE.Vector2(0.5, 0.5)) }), size: 1, height: 0.1, curveSegments: 12, bevelEnabled: false }); textGeometry.center(); ``` - 创建文字几何体,这里尝试使用自定义字体解析,但可能存在问题,因为自定义字体解析需要正确的字体数据。 ```javascript // 动画函数 function animate() { requestAnimationFrame(animate); // 粒子旋转动画 particlesMesh.rotation.x += 0.001; particlesMesh.rotation.y += 0.001; renderer.render(scene, camera); } animate(); // 窗口 resize 处理 window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); ``` - 定义动画函数,使用`requestAnimationFrame`实现粒子的旋转动画。 - 监听窗口大小变化事件,更新相机的投影矩阵和渲染器的大小。 ### ⚠️存在的问题 - **字体解析问题**:`THREE.FontLoader().parse`中的参数并不是有效的字体数据,应该使用`FontLoader`加载有效的字体文件(`.json`格式)。 - **文字未添加到场景**:文字几何体创建后,没有将其添加到场景中。 ### 🛠️改进建议 - **加载正确的字体文件**:可以从Three.js官方示例中下载字体文件,然后使用`FontLoader`加载。 - **将文字添加到场景**:创建文字材质和文字网格,并将其添加到场景中。 以下是改进后的代码: ```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>生日祝福粒子动画</title> <style> body { margin: 0; overflow: hidden; background: #000; } canvas { display: block; } </style> </head> <body> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.160.0/build/three.module.js", "three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/" } } </script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { FontLoader } from 'three/addons/loaders/FontLoader.js'; // 初始化场景、相机、渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 轨道控制器,用于交互 const controls = new OrbitControls(camera, renderer.domElement); camera.position.z = 5; // 粒子材质 const particleMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 0.05, transparent: true, depthTest: false, blending: THREE.AdditiveBlending }); // 生成粒子几何体 const particlesGeometry = new THREE.BufferGeometry(); const particlesCount = 10000; const posArray = new Float32Array(particlesCount * 3); for (let i = 0; i < particlesCount * 3; i++) { posArray[i] = (Math.random() - 0.5) * 10; } particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3)); // 粒子对象 const particlesMesh = new THREE.Points(particlesGeometry, particleMaterial); scene.add(particlesMesh); // 加载字体 const fontLoader = new FontLoader(); fontLoader.load('https://unpkg.com/three@0.160.0/examples/fonts/helvetiker_regular.typeface.json', (font) => { // 文字形状(这里以“生日快乐”为例,可根据需要修改) const textGeometry = new THREE.TextGeometry('生日快乐', { font: font, size: 1, height: 0.1, curveSegments: 12, bevelEnabled: false }); textGeometry.center(); const textMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff }); const textMesh = new THREE.Mesh(textGeometry, textMaterial); scene.add(textMesh); }); // 动画函数 function animate() { requestAnimationFrame(animate); // 粒子旋转动画 particlesMesh.rotation.x += 0.001; particlesMesh.rotation.y += 0.001; renderer.render(scene, camera); } animate(); // 窗口 resize 处理 window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); </script> </body> </html> ``` ### 📚学习资源 - **Three.js官方文档**:https://threejs.org/docs/ - **Three.js官方示例**:https://threejs.org/examples/ ######[AI写代码神器 | 2272点数解答 | 2026-03-15 13:59:03]

相关提问
本站限时免费提问中
实用工具查看更多
Linux在线手册 [开发类]
Jquery在线手册 [开发类]
今日油价 [生活类]
图片互转base64 [开发类]
时间转换器 [开发类]