wordpress网站部署,宁波企业网站设计,网站建设技术的发展,ps设计网页个人简介 #x1f440;个人主页#xff1a; 前端杂货铺 ⚡开源项目#xff1a; rich-vue3 #xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL#xff09; #x1f64b;♂️学习方向#xff1a; 主攻前端方向#xff0c;正逐渐往全干发展 #x1…个人简介 个人主页 前端杂货铺 ⚡开源项目 rich-vue3 基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL ♂️学习方向 主攻前端方向正逐渐往全干发展 个人状态 研发工程师现效力于中国工业软件事业 人生格言 积跬步至千里积小流成江海 推荐学习开源 rich-vue3 前端面试宝典 Vue2 Vue3 Vue2/3项目实战 Node.js实战 Three.js 个人推广每篇文章最下方都有加入方式旨在交流学习资源分享快加入进来吧 内容参考链接THREE.JS 专栏Three.js 入门 文章目录 前言项目概况源码路径文件结构与职责 写在最后 前言
大家好这里是前端杂货铺。
这篇文章我们使用 Vue3TypeScriptThree.js 等主流前端技术打造 雨雪交加的智慧城市 项目。 three.js-雨雪交加的智慧城市 项目源码 请点击此处自行获取 [github] rich-vue3
如果此项目对你有些帮助欢迎给个免费的 Star Thanks♪(ω) 项目概况
源码路径
该项目已被托管到 rich-vue3 中具体源码在 rich-vue3 项目的 rich-vue3-webapp/src/views/city-three 路径。
文件结构与职责
下面是该项目涉及到文件的基本结构
base/index.css页面的基础样式config/index.ts存储项目中需要使用的颜色effect/… 各种效果及特效包括 天空盒子、扩散半球、扩散圆、旋转四棱锥、飞线、文字、雷达、雨、路径运动、烟雾、雪、建筑物外围线条、透明墙等enter/initCity.ts初始化场景、 创建城市实例、监听浏览器变化、动画enter/city.ts城市类加载城市模型、初始化各种效果、点击聚焦和滑动滑轮缩放utils/index.ts封装加载城市模型的方法index.vue基本 UI初始化项目的入口 城市类代码如下在 initEffect() 方法中会创建很多种效果。
import { loadFBX } from ../utils
import * as THREE from three
import * as TWEEN from tweenjs/tween.js
import { SurroundLine } from /views/city-three/effect/surroundLine
import { Background } from /views/city-three/effect/background
import { Radar } from ../effect/radar
import { Wall } from ../effect/wall
import { Circle } from /views/city-three/effect/circle
import { Ball } from /views/city-three/effect/ball
import { Cone } from /views/city-three/effect/cone
import { Fly } from /views/city-three/effect/fly
import { Road } from /views/city-three/effect/road
import { Font } from /views/city-three/effect/font
import { Snow } from /views/city-three/effect/snow
import { Rain } from /views/city-three/effect/rain
import { Smoke } from /views/city-three/effect/smoke;export class City {private readonly scene: anyprivate readonly camera: anyprivate readonly controls: anyprivate tweenPosition: anyprivate tweenRotation: anyprivate flag: booleanprivate readonly height: { value: number }private readonly time: { value: number }private readonly top: { value: number }private readonly effect: {snow: anyrain: anysmoke: any}constructor(scene: object, camera: object, controls: any) {this.scene scenethis.camera camerathis.controls controlsthis.flag falsethis.tweenPosition nullthis.tweenRotation nullthis.height {value: 5}this.time {value: 0}this.top {value: 0}// 雪、雨、烟雾this.effect {snow: null,rain: null,smoke: null}this.loadCity()}loadCity() {// 加载城市模型并且渲染到画布loadFBX(model/beijing.fbx).then((object: any) {object.traverse((child: any) {if (child.isMesh) {new SurroundLine(this.scene, child, this.height, this.time)}})this.initEffect()})}// 初始化效果各个功能点都放在了这里initEffect() {new Background(this.scene)new Radar(this.scene, this.time)new Wall(this.scene, this.time)new Circle(this.scene, this.time)new Ball(this.scene, this.time)new Cone(this.scene, this.top, this.height)new Fly(this.scene, this.time)new Road(this.scene, this.time)new Font(this.scene)this.effect.snow new Snow(this.scene)this.effect.rain new Rain(this.scene)this.effect.smoke new Smoke(this.scene)// 点击选择this.addClick()this.addWheel()}addClick() {let flag truedocument.onmousedown () {flag truedocument.onmousemove () {flag false}}document.onmouseup (event) {if (flag) {this.clickEvent(event)}document.onmousemove null}}// 场景跟随鼠标坐标缩放addWheel() {const body: HTMLElement document.body// ts-ignorebody.onmousewheel (event: MouseEvent) {// 鼠标当前的坐标const x (event.clientX / window.innerWidth) * 2 - 1const y -(event.clientY / window.innerHeight) * 2 1const value 30const vector new THREE.Vector3(x, y, 0.5)vector.unproject(this.camera)vector.sub(this.camera.position).normalize()// ts-ignoreif (event.wheelDelta 0) {this.camera.position.x vector.x * valuethis.camera.position.y vector.y * valuethis.camera.position.z vector.z * valuethis.controls.target.x vector.x * valuethis.controls.target.y vector.y * valuethis.controls.target.z vector.z * value} else {this.camera.position.x - vector.x * valuethis.camera.position.y - vector.y * valuethis.camera.position.z - vector.z * valuethis.controls.target.x - vector.x * valuethis.controls.target.y - vector.y * valuethis.controls.target.z - vector.z * value}}}// 点击聚焦clickEvent(event: MouseEvent) {// 归一化坐标将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to 1)const x (event.clientX / window.innerWidth) * 2 - 1const y -(event.clientY / window.innerHeight) * 2 1// 创建设备坐标三维const standardVector new THREE.Vector3(x, y, 0.5)// 转化为世界坐标 (将此向量 (坐标) 从相机的标准化设备坐标 (NDC) 空间投影到世界空间)const worldVector standardVector.unproject(this.camera)// 做序列化const ray worldVector.sub(this.camera.position).normalize()// 实现点击选中// 创建一个射线发射器用来发射一条射线const raycaster new THREE.Raycaster(this.camera.position, ray)// 返回射线碰撞到的物体const intersects raycaster.intersectObjects(this.scene.children, true)let point3d nullif (intersects.length) {point3d intersects[0]}if (point3d) {const proportion 3// 开始动画修改观察点const time 1000this.tweenPosition new TWEEN.Tween(this.camera.position).to({ x: point3d.point.x * proportion, y: point3d.point.y * proportion, z: point3d.point.y * proportion }, time).start()this.tweenRotation new TWEEN.Tween(this.camera.rotation).to({ x: this.camera.rotation.x, y: this.camera.rotation.y, z: this.camera.rotation.z }, time).start()}}start(delta: number) {for (const key in this.effect) {// ts-ignorethis.effect[key] this.effect[key].animation()}if (this.tweenPosition this.tweenRotation) {this.tweenPosition.update()this.tweenRotation.update()}this.height.value 0.4if (this.height.value 160) {this.height.value 5}this.time.value deltaif (this.top.value 15 || this.top.value 0) {this.flag !this.flag}this.top.value this.flag ? -0.8 : 0.8}
}写在最后
由于本项目涉及到的代码较多在本篇文章中就不一一讲解了感兴趣的同学可以去下载项目源码自行学习有问题的话可以评论区一起讨论交流~
好啦本篇文章到这里就要和大家说再见啦祝你这篇文章阅读愉快你下篇文章的阅读愉快留着我下篇文章再祝 参考资料 Three.js 官方文档WebGLThree.js 入门与实战【作者慕课网_yancy】