vue+three.js實現3d系統的搭建

1.首先node.js是12.22版本的,安裝three.js可以參考這篇文章

直接用Threejs入門-安裝教程_安裝three.js-CSDN博客

直接在終端安裝three.js即可

npm install --save three

在相同目錄下安裝vite構建工具

npm install --save-dev vite

在項目里面看package.json中是否有"three": "^0.164.1",有就安裝好了。

然后就使用吧,這里舉個例子

<template><div><canvas id="three"></canvas></div>
</template><script>
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'export default {mounted() {this.initThree()},methods: {initThree() {const scene = new THREE.Scene()//There are a few different cameras in three.js. For now, let's use a PerspectiveCamera.//three.js 里有幾種不同的相機,在這里,我們使用的是 PerspectiveCamera(透視攝像機)。//第一個參數是視野角度(FOV)。視野角度就是無論在什么時候,你所能在顯示器上看到的場景的范圍,它的單位是角度(與弧度區分開)。//第二個參數是長寬比(aspect ratio)。 也就是你用一個物體的寬除以它的高的值。比如說,當你在一個寬屏電視上播放老電影時,可以看到圖像仿佛是被壓扁的。/** 接下來的兩個參數是近截面(near)和遠截面(far)。* 當物體某些部分比攝像機的遠截面遠或者比近截面近的時候,該這些部分將不會被渲染到場景中。* 或許現在你不用擔心這個值的影響,但未來為了獲得更好的渲染性能,你將可以在你的應用程序里去設置它。* */const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)const renderer = new THREE.WebGLRenderer()/** 除了創建一個渲染器的實例之外,我們還需要在我們的應用程序里設置一個渲染器的尺寸。* 比如說,我們可以使用所需要的渲染區域的寬高,來讓渲染器渲染出的場景填充滿我們的應用程序。* 因此,我們可以將渲染器寬高設置為瀏覽器窗口寬高。* 對于性能比較敏感的應用程序來說,你可以使用 setSize 傳入一個較小的值,例如 window.innerWidth/2 和 window.innerHeight/2,這將使得應用程序在渲染時,以一半的長寬尺寸渲染場景。* 如果你希望保持你的應用程序的尺寸,是以較低的分辨率來渲染,你可以在調用 setSize 時,將 updateStyle(第三個參數)設為 false。* 例如,假設你的 <canvas> 標簽現在已經具有了 100% 的寬和高,調用 setSize(window.innerWidth/2, window.innerHeight/2, false) 將使得你的應用程序以四分之一的大小來進行渲染。* */renderer.setSize(window.innerWidth, window.innerHeight)document.body.appendChild(renderer.domElement)/** 最后一步很重要,我們將 renderer(渲染器)的dom元素(renderer.domElement)添加到我們的 HTML 文檔中。* 這就是渲染器用來顯示場景給我們看的 <canvas> 元素。* *///To create a cube, we need a BoxGeometry. This is an object that contains all the points (vertices) and fill (faces) of the cube. We'll explore this more in the future.//要創建一個立方體,我們需要一個 BoxGeometry(立方體)對象. 這個對象包含了一個立方體中所有的頂點(vertices)和面(faces)。未來我們將在這方面進行更多的探索。const geometry = new THREE.BoxGeometry(1, 1, 1)//接下來,對于這個立方體,我們需要給它一個材質,來讓它有顏色。//Three.js 自帶了幾種材質,在這里我們使用的是 MeshBasicMaterial。/** 所有的材質都存有應用于他們的屬性的對象。* 在這里為了簡單起見,我們只設置一個color屬性,值為 0x00ff00,也就是綠色。* 這里所做的事情,和在 CSS 或者 Photoshop 中使用十六進制(hex colors)顏色格式來設置顏色的方式一致。* */const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })/** 第三步,我們需要一個 Mesh(網格)。* 網格包含一個幾何體以及作用在此幾何體上的材質,我們可以直接將網格對象放入到我們的場景中,并讓它在場景中自由移動。* */const cube = new THREE.Mesh(geometry, material)/** 默認情況下,當我們調用 scene.add() 的時候,物體將會被添加到 (0,0,0) 坐標。* 但將使得攝像機和立方體彼此在一起。為了防止這種情況的發生,我們只需要將攝像機稍微向外移動一些即可。* */scene.add(cube)camera.position.z = 5//渲染場景/** 現在,如果將之前寫好的代碼復制到HTML文件中,你不會在頁面中看到任何東西。* 這是因為我們還沒有對它進行真正的渲染。* 為此,我們需要使用一個被叫做“渲染循環”(render loop)或者“動畫循環”(animate loop)的東西。* */function animate() {requestAnimationFrame(animate)//使立方體動起來/** 在開始之前,如果你已經將上面的代碼寫入到了你所創建的文件中,你可以看到一個綠色的方塊。* 讓我們來做一些更加有趣的事 —— 讓它旋轉起來。* 將下列代碼添加到 animate() 函數中 renderer.render 調用的上方:* */cube.rotation.x += 0.01cube.rotation.y += 0.01renderer.render(scene, camera)}animate()function resizeRendererToDisplaySize(renderer) {const canvas = renderer.domElementvar width = window.innerWidthvar height = window.innerHeightvar canvasPixelWidth = canvas.width / window.devicePixelRatiovar canvasPixelHeight = canvas.height / window.devicePixelRatioconst needResize = canvasPixelWidth !== width || canvasPixelHeight !== heightif (needResize) {renderer.setSize(width, height, false)}return needResize}},},
}
</script><style scoped>
#three {width: 100%;height: 100%;position: fixed;left: 0;top: 0;
}
</style>

結果如下:

在終端運行

2.2024/5/28

點云數據上傳

<template><div><input type="file" id="csvFile" accept=".csv" @click="handleClick" style="pointer-events: auto" /><div style="width: 100%; height: 100vh; position: relative"><canvas id="three"></canvas><div id="overlay" style="position: absolute; top: 0; left: 0; pointer-events: auto"><div class="button-container"><!-- pointer-events: auto下面的元素相應鼠標觸摸點擊事件,這是默認的     --><!--        <button id="myButton">BUTTON</button>--></div></div></div></div>
</template><script>
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import Papa from 'papaparse'export default {mounted() {this.initThree()// 下面 window.addEventListene是添加一個它會添加一個事件監聽器到window對象上,以監聽resize事件。當瀏覽器窗口大小改變時,這個事件會被觸發,并執行this.onWindowResize這個方法。注意,這里的this.onWindowResize應該是一個在Vue組件的methods中定義的方法,用于處理窗口大小改變時的邏輯(例如更新攝像機的縱橫比或重新渲染場景)。// 將onWindowResize組件里面的方塊不會隨著外邊框的放大縮小而發生變化window.addEventListener('resize', this.onWindowResize, false)},beforeDestroy() {window.removeEventListener('resize', this.onWindowResize, false)// 在這里添加其他清理代碼,比如取消動畫等},methods: {handleClick() {console.log('Input clicked!')},initThree() {const canvas = document.getElementById('three')const renderer = new THREE.WebGLRenderer({ canvas })renderer.setSize(window.innerWidth, window.innerHeight)const scene = new THREE.Scene()scene.background = new THREE.Color('#ccc')scene.environment = new THREE.Color('#ccc')// 創建一個光源,因為默認的THREE.Scene是沒有光源的const light = new THREE.AmbientLight(0x404040) // soft white lightscene.add(light)// 初始化相機,設置其位置const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)camera.position.z = 5 // 把相機向后移動一些,以便能看到場景中的物體const controls = new OrbitControls(camera, renderer.domElement)controls.update()// 設置一下參數const b = 1const geometry = new THREE.BoxGeometry(b, 1, 1)const material = new THREE.MeshBasicMaterial({ color: 0xfff })// const cube = new THREE.Mesh(geometry, material)// cube.position.x += 4// scene.add(cube)// const geometry1 = new THREE.ConeGeometry(1, 1, 32)// const cone = new THREE.Mesh(geometry1, material)// scene.add(cone)const geometry2 = new THREE.SphereGeometry(1, 32, 10)// const sphere = new THREE.Mesh(geometry2, material)// scene.add(sphere)const csvFileInput = document.getElementById('csvFile')csvFileInput.addEventListener('change', function (e) {const file = e.target.files[0]if (file) {const reader = new FileReader()reader.onload = function (e) {const text = e.target.result // 讀取的文件內容const lines = text.split('\n') // 按行分割// 跳過標題行(如果有)let dataLines = lines.slice(1)// 解析點和顏色數據const points = []const colors = []for (let i = 0; i < dataLines.length; i++) {const lineData = dataLines[i].split(',') // 按逗號分割每行數據if (lineData.length === 6) {// 假設每行包含7個元素(x, y, z, r, g, b, a)points.push(parseFloat(lineData[0]), parseFloat(lineData[1]), parseFloat(lineData[2]))colors.push(parseFloat(lineData[3]), parseFloat(lineData[4]), parseFloat(lineData[5]))}}// 創建Float32Arrayconst pointsArray = new Float32Array(points)const colorsArray = new Float32Array(colors)const geometry3 = new THREE.BufferGeometry()geometry3.setAttribute('position', new THREE.BufferAttribute(pointsArray, 3))if (colors) {geometry3.setAttribute('color', new THREE.BufferAttribute(colorsArray, 3)) // 假設每個顏色由 4 個浮點數表示(RGBA)}const material1 = new THREE.PointsMaterial({size: 0.05, // 點的大小vertexColors: true, // 如果使用了顏色數組,則啟用此選項// 其他屬性...})const pointsObject = new THREE.Points(geometry3, material1)scene.add(pointsObject)// 在這里,你可以使用WebGL或其他圖形API來渲染這些數據// ...}reader.readAsText(file) // 以文本格式讀取文件}})// sphere.position.x = -4camera.position.z = 5// 加載模型(這里只是一個示例,你可能需要替換為你的模型)// 渲染循環function animate() {requestAnimationFrame(animate)// cube.rotation.x += 0.01// cube.rotation.y += 0.01// cone.rotation.x += 0.01// cone.rotation.y += 0.01// sphere.rotation.x += 0.01// sphere.rotation.y += 0.01renderer.render(scene, camera)}animate()// 窗口大小變化時的處理函數this.onWindowResize = () => {camera.aspect = window.innerWidth / window.innerHeightcamera.updateProjectionMatrix()renderer.setSize(window.innerWidth, window.innerHeight)}// 如果使用OrbitControls,可以在這里初始化它// const controls = new OrbitControls(camera, renderer.domElement)},},
}
</script>
<style scoped>
#csvFile {width: 100px;height: 100px;z-index: 265; /* 確保按鈕在畫布之上265大于100所以能放在前面 */
}
#three {position: absolute;width: 100%;text-align: center;z-index: 100;display: block;
}
#overlay {width: 100%;height: 100%;display: flex;/*  垂直方向排列column*/flex-direction: column;align-items: center;/*  center意味著子元素將在垂直方向上居中對齊。*//*justify-content: center;*/pointer-events: none;
}
#overlay button {pointer-events: auto; /* 允許按鈕上的點擊事件 */
}
.button-container {margin-top: 1px; /* 使得元素在垂直方向上被推到容器的底部 */align-self: flex-end; /* 在水平方向上對齊到容器的右邊 */pointer-events: none; /* 這個可能不需要,除非你想要防止容器本身接收點擊事件 */z-index: 267;
}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/17567.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/17567.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/17567.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

神秘顧客調查:第三方渠道監測如何操作?

第三方渠道監測是指通過專業的第三方機構或服務商&#xff0c;對企業的銷售渠道進行系統化的監督和評估。這種監測幫助企業了解各渠道的表現&#xff0c;確保合規性&#xff0c;提升市場競爭力。深圳神秘顧客市場調查限公司&#xff08;SMS&#xff09;總結了第三方渠道監測的操…

【安裝筆記-20240528-Linux-在 Vultr 云服務器上安裝 OpenWRT】

安裝筆記-系列文章目錄 安裝筆記-20240528-Linux-在 Vultr 云服務器上安裝測試 OpenWRT 文章目錄 安裝筆記-系列文章目錄安裝筆記-20240528-Linux-在 Vultr 云服務器上安裝測試 OpenWRT 前言一、軟件介紹名稱&#xff1a;OpenWRT主頁官方介紹 二、安裝步驟測試版本&#xff1a…

多function-calling 調用

多function-calling 調用 接上一篇function-calling調用&#xff0c;本篇實現了一個多function-calling的調用。OpenAI會根據function的描述自己來判斷應該調用哪個function。最終調用function的動作是由我們來決定的&#xff0c;當然你也可以不調對應的函數。 兩個函數分別是…

案例研究|MeterSphere助力萬物云構建高效自動化測試平臺

萬物云空間科技服務股份有限公司&#xff08;以下簡稱為“萬物云”&#xff09;&#xff0c;前身為萬科物業發展股份有限公司&#xff0c;是國內領先的物管龍頭上市公司。作為一家科技引領的全域空間服務商&#xff0c;萬物云致力于打造產業級共享服務平臺&#xff0c;基于空間…

1. lambda初體驗

首先聲明一個函數式接口&#xff0c;就只接口內只有一個抽象方法 //函數式接口 public interface Factory {Object getObject();}接口實現類 public class SubClass implements Factory {Overridepublic Object getObject() {return new User();}}User類 public class User …

酒店提前線上訂房小程序源碼系統 PHP+MySQL組合開發 源碼開源可二開 帶完整的安裝代碼包以及搭建教程

系統概述 隨著移動互聯網的普及&#xff0c;越來越多的人習慣通過手機進行酒店預訂。傳統的線下訂房方式逐漸無法滿足用戶的需求&#xff0c;酒店提前線上訂房小程序的出現成為必然趨勢。該源碼系統的開發旨在為酒店提供一個便捷、高效的線上訂房平臺&#xff0c;提升用戶體驗…

基于微信小程序+ JAVA后端實現的【醫院掛號預約系統】 設計與實現 (內附設計LW + PPT+ 源碼+ 演示視頻 下載)

項目名稱 項目名稱&#xff1a; 《基于微信小程序的醫院掛號預約系統設計與實現》 項目技術棧 該項目采用了以下核心技術棧&#xff1a; 后端框架/庫&#xff1a; Java, SSM框架數據庫&#xff1a; MySQL前端技術&#xff1a; 微信小程序, uni-app 項目展示 全文概括 本…

設置單群聊消息擴展

根據消息 ID &#xff0c;對單聊會話或群聊會話中已經發送的消息設置擴展信息。每次最多可以設置 100 個擴展屬性信息&#xff0c;最多可設置 300 個。 通過 Server API 操作消息擴展&#xff0c;默認不會向操作者的客戶端同步&#xff0c;會導致擴展信息不一致。如有需要&…

MySQL觸發器實戰:自動執行的秘密

歡迎來到我的博客&#xff0c;代碼的世界里&#xff0c;每一行都是一個故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交給時間 &#x1f3e0; &#xff1a;小破站 MySQL觸發器實戰&#xff1a;自動執行的秘密 前言觸發器的定義和作用觸發器的定義和作用觸發器的…

大模型領域新聞跟蹤

楊值麟 月之暗面楊植麟&#xff1a;大模型開發是“承包森林”月之暗面集結最強創投&#xff0c;“清華師姐”是最強“助攻”月之暗面楊植麟&#xff1a;互聯網研發是“種樹”&#xff0c;大模型研發是“承包森林”月之暗面楊植麟復盤大模型創業這一年&#xff1a;向延綿而未知…

搜維爾科技:穿上Xsens Link動作捕捉套裝,進行精準的運動捕捉

穿上Xsens Link動作捕捉套裝&#xff0c;進行精準的運動捕捉 搜維爾科技&#xff1a;穿上Xsens Link動作捕捉套裝&#xff0c;進行精準的運動捕捉

vue 筆記01

目錄 01 vuejs中屬性的基本使用 02 v-show指令的使用 03 v-if 指令的使用 04 v-for指令的使用 05 v-model 指令 06 template模板標簽 07 v-on事件的綁定指令 08 事件中的event對象 01 vuejs中屬性的基本使用 {{ }} 叫做mustache模板語法 雙花括號 小胡子語法 雙花括號…

安卓手機APP開發__構建通話應用

安卓手機APP開發__構建通話應用 目錄 概述 依賴項和權限 注冊應用 平臺集成 注冊通話 添加通話 接聽來電 拒接來電 去電 將通話置于保持狀態 斷開連接 轉接音頻 前臺支持 Surface 支持 概述 使用 Telecom Jetpack 庫為用戶提供最佳視頻和音頻體驗。借助 Teleco…

GO語言 linux部署

https://blog.csdn.net/wangye135/article/details/136177171 一、簡述 1. 可以直接在服務器上運行編譯好的二進制文件&#xff0c;不需要在服務器上下載語言環境。 2. 內置運行時環境&#xff1a;可執行文件中內置了運行時環境&#xff0c;包括垃圾回收、調度器等&#xff…

Java深拷貝淺拷貝

在Java中&#xff0c;深拷貝和淺拷貝是兩種不同的對象復制方式。 淺拷貝&#xff1a;創建一個新對象&#xff0c;然后將原對象的非靜態字段復制到新對象中。如果字段是值類型的&#xff0c;那么對該字段執行逐位復制。如果字段是引用類型的&#xff0c;則復制引用但不復制引用的…

SAP 根據報錯消息號快速定位問題

通常用戶在業務的操作過程中&#xff0c;經常會遇到報錯信息&#xff0c;有些報錯是系統控制拋出的信息&#xff0c;但是有些報錯的信息是根據不同地點業務場景對填寫的數據進行判斷校驗&#xff0c;然后給出的報錯信息&#xff0c;正常情況報錯信息一般是有文本&#xff0c;或…

【C語言】文件操作講解

C語言文件操作講解 文件文件名文件類型數據在內存中的存儲 文件緩沖區文件指針文件的打開與關閉fopenfclosefopen與fclose的使用文件的打開方式 文件的順序讀寫fputcfgetcfputsfgetsfprintffscanffwritefread輸入流與輸出流對比scanf\fscanf\sscanf與printf\fprintf\sprintfssc…

【區分vue2和vue3下的elementUI和elementUI Plus的button組件,介紹如何安裝,屬性,事件,方法等以及使用案例】

區分vue2下的Element UI和vue3下的Element Plus的Button組件 Element UI (vue2) Button組件&#xff1a;基于Vue 2的Element UI庫中的Button組件提供了多種樣式和類型&#xff0c;如默認、主要、成功、警告、危險等。 Element Plus (vue3) Button組件&#xff1a;作為Element …

匯編原理(二)寄存器——內存訪問

一個字 兩個字節 雙字 字節為8位 字為16位&#xff08;看兩格&#xff09; 雙子dword32位&#xff08;看四格&#xff09; 內存中字的存儲&#xff1a; 0地址單元中存放的字節型數據是多少&#xff1f; 0地址字單元中存放的字型數據是多少&#xff1f; 2地址字單元中存放…

Secure Operation

文章目錄 Secure Summation OperationSecure Set Union Operation Secure Summation Operation 讓我們通過一個具體的例子來說明這個算法。 假設有三個數據擁有者 S1, S2 和 S3&#xff0c;他們分別持有以下值&#xff1a; S1 持有 value1 10S2 持有 value2 20S3 持有 val…