当前位置: 首页 > ai >正文

vue+threeJs 生成烟花效果

        嗨,我是小路。今天主要和大家分享的主题是“vue+threeJs 生成烟花效果”。        

今天在找找three,js项目进行练习,主要寻找的是生成烟花的效果。今天主要对整个项目的构建过程进行复盘。

1.以AI为导师

注意:在准备练习到时找案例,准备直接通过deepseek或者通义千问生成对应的代码,直接生成想要学习的案例,但实际效果不理想。主要有三个原因:

1、生成的代码比较老旧。在生成的代码中,还使用geometry生成自定义模型,而现在的three.js版本基本使用的bufferGeometry来生成。

2、生成的项目欠缺,在本地的环境中跑不起来。本地环境和线上的不一致,ai不会考虑这个代码能不能执行成功,而且代码里面有部分内容确实,根本生成不了想要的效果。

3、生成的代码不是自己想要的。想通过AI生成项目来练习,需要不停的多次修改提示词,这样才会偶尔生成自己想要的项目出来;更多的是生成的是一些带插件的代码的项目,没有通过练习提升掌握three.js框架的作用。

其优点就是:项目的注释说明很清晰,生成步骤很清晰,让人更容易寻找思路去做项目。

2.以代码为师

注意:在github和gitee上有很多three.js项目的项目,这些都可以下载下来进行项目联系,不仅可以提升自己对three.js框架的运用,掌握他的代码技巧。

如在当前项目中,直接是生成了一个class类进行封装;但自己在运用时,更习惯的运用vue3的方法,const 成一个个函数;

在vue的框架中,运用three.js更多的是重新生成canvas进行渲染;较少运用vue的双向绑定。

二、实例代码

<template><div class="pageBox"><div class="leftBox" ref="leftRef"></div><div class="rightBox" ref="rightRef" :style="{ background: bgColor }"></div></div></template>
<script setup>
import { onMounted, reactive, ref } from 'vue';
import * as THREE from 'three';
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const bgColor = ref("")const leftRef = ref();
const rightRef = ref()
// 定义相机输出画布的尺寸(单位:像素px)
let width = window.innerWidth; //宽度
let height = window.innerHeight; //高度
// 创建3D场景对象Scene
const scene = new THREE.Scene();
//设置背景色
scene.background = new THREE.Color(0x002244);const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
camera.position.z = 50;// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();const createLight = () => {const pointLight = new THREE.PointLight(0xffffff, 0.8);pointLight.position.set(10, 10, 10);scene.add(pointLight);// 添加光源和背景等(可选)const ambientLight = new THREE.AmbientLight(0xffffff, 0.8); // 环境光scene.add(ambientLight);
}/*** 烟花粒子类* 负责创建和管理单个烟花的所有粒子*/
class Firework {constructor(x, y, z) {// 初始化属性this.particles = []; // 粒子数组this.geometry = new THREE.BufferGeometry(); // 粒子几何体this.count = 10000; // 粒子数量this.positions = new Float32Array(this.count * 3); // 粒子位置数组this.velocities = []; // 粒子速度数组this.colors = new Float32Array(this.count * 3); // 粒子颜色数组this.sizes = new Float32Array(this.count); // 粒子大小数组this.life = new Float32Array(this.count); // 粒子生命周期数组// 初始化每个粒子for (let i = 0; i < this.count; i++) {// 使用球面坐标系计算粒子初始方向const phi = Math.random() * Math.PI * 2; // 水平角度const theta = Math.random() * Math.PI; // 垂直角度const velocity = 2 + Math.random() * 2; // 随机速度// 计算粒子速度向量this.velocities.push(velocity * Math.sin(theta) * Math.cos(phi), // x方向速度velocity * Math.sin(theta) * Math.sin(phi), // y方向速度velocity * Math.cos(theta) // z方向速度);// 设置粒子初始位置this.positions[i * 3] = x; // x坐标this.positions[i * 3 + 1] = y; // y坐标this.positions[i * 3 + 2] = z; // z坐标// 设置粒子颜色(红色为主,带随机变化)this.colors[i * 3] = 1.0; // 红色通道this.colors[i * 3 + 1] = Math.random() * 0.2; // 绿色通道this.colors[i * 3 + 2] = Math.random() * 0.2; // 蓝色通道// 初始化粒子大小和生命值this.sizes[i] = 0.3; // 初始大小this.life[i] = 1.0; // 初始生命值}// 设置几何体属性this.geometry.setAttribute("position",new THREE.BufferAttribute(this.positions, 3));this.geometry.setAttribute("color",new THREE.BufferAttribute(this.colors, 3));this.geometry.setAttribute("size",new THREE.BufferAttribute(this.sizes, 1));// 创建粒子材质const material = new THREE.PointsMaterial({size: 0.3, // 粒子大小vertexColors: true, // 启用顶点颜色blending: THREE.AdditiveBlending, // 使用加法混合transparent: true, // 启用透明opacity: 0.8, // 设置透明度});// 创建粒子系统并添加到场景this.points = new THREE.Points(this.geometry, material);scene.add(this.points);}// 更新烟花状态update() {let alive = false;for (let i = 0; i < this.count; i++) {if (this.life[i] > 0) {alive = true;// 根据速度更新位置this.positions[i * 3] += this.velocities[i * 3] * 0.1;this.positions[i * 3 + 1] += this.velocities[i * 3 + 1] * 0.1;this.positions[i * 3 + 2] += this.velocities[i * 3 + 2] * 0.1;// 添加重力效果this.velocities[i * 3 + 1] -= 0.05;// 更新生命值和大小this.life[i] -= 0.015;this.sizes[i] = this.life[i] * 0.3;}}// 标记属性需要更新this.geometry.attributes.position.needsUpdate = true;this.geometry.attributes.size.needsUpdate = true;return alive; // 返回是否还有活着的粒子}// 清理烟花资源dispose() {scene.remove(this.points); // 从场景中移除this.geometry.dispose(); // 释放几何体this.points.material.dispose(); // 释放材质}
}
const fireworks = [];
/*** 创建随机位置的烟花* 在场景的合理范围内随机选择位置*/
const createRandomFirework = () => {const x = (Math.random() * 2 - 1) * 30; // x范围:-30到30const y = (Math.random() * 2 - 1) * 25; // y范围:-25到25const z = (Math.random() * 2 - 1) * 25; // y范围:-25到25fireworks.push(new Firework(x, y, z));
}onMounted(() => {initData()//添加相机空间const controls = new OrbitControls(camera, renderer.domElement);// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景controls.addEventListener('change', function () {renderer.render(scene, camera); //执行渲染操作});//监听鼠标、键盘事件renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)//将innerHTML置空,避免append重复添加渲染leftRef.value.innerHTML = ''leftRef.value.append(renderer.domElement);})
const initData = () => {createLight();render();
}
function render() {requestAnimationFrame(render);// 有5%的概率生成新烟花if (Math.random() < 0.05) {createRandomFirework();}// 更新所有烟花,移除已经消失的烟花for (let i = fireworks.length - 1; i >= 0; i--) {const alive = fireworks[i].update();if (!alive) {fireworks[i].dispose();fireworks.splice(i, 1);}}renderer.render(scene, camera);
}</script>
<style scoped lang="less">
.pageBox {width: 100%;height: 100vh;padding: 0;margin: 0;display: flex;justify-content: space-between;align-items: center;.rightBox {width: 100%;height: 100%;}
}
</style>

三、复盘总结

       三人行,必有我师;别忘了,还可以以AI为师!

都看到这里了,记得【点赞】+【关注】哟。

参考文章:

使用 Three.js 创建烟花粒子特效教程_threejs 粒子特效-CSDN博客

http://www.xdnf.cn/news/7610.html

相关文章:

  • PEFT简介及微调大模型DeepSeek-R1-Distill-Qwen-1.5B
  • 【css知识】flex-grow: 1
  • LibreHardwareMonitor:.Net开发的开源硬件监控项目
  • 中国机加工的市场概况及冷镦技术对于机加工替代的趋势
  • 如何在 Windows 11/10 PC 上擦除外部硬盘驱动
  • 什么叫生成式人工智能?职业技能的范式转移与能力重构
  • HarmonyOS5云服务技术分享--云存储SDK文章整理
  • 2025年 全国青少年信息素养大赛 算法创意挑战赛C++ 初中组 初赛真题
  • 94.LabelGrid 的遍历与属性编辑 Maui例子 C#例子
  • BioID技术:探索蛋白质相互作用的新方法
  • Java 05正则表达式
  • Linux中FTP服务命令使用与NFS服务
  • JavaScript的Button的contentItem属性
  • 企业建私有云,选择K8S方案会怎么样?
  • [洛谷刷题12]
  • COMSOL软件入门
  • 《棒球知识百科》亚冬会有哪些国家参加·棒球1号位
  • 后期:daplink
  • 基于CNN的猫狗识别(自定义Resnet-18模型)
  • 生产消费者模型 读写者模型
  • 学术前沿!IEEE PRMVAI 2025多模态深度学习研讨会来袭
  • 19 C 语言位运算、赋值、条件、逗号运算符详解:涵盖运算符优先级与复杂表达式计算过程分析
  • OpenCV CUDA 模块特征检测与描述------在GPU上执行特征描述符匹配的类cv::cuda::DescriptorMatcher
  • Openwrt Time Zones和TZ string对应关系表
  • TuyaOpen横空出世!涂鸦智能如何用开源框架重构AIoT开发范式?
  • 多线程(六)
  • 安装完dockers后就无法联网了,执行sudo nmcli con up Company-WiFi,一直在加载中
  • 打卡第二十三天
  • 哈希查找方法
  • 《微机原理与接口技术》第 8 章 常用接口芯片