3D可視化編輯器模版

體驗地址:http://mute.turntip.cn

在這里插入圖片描述
在這里插入圖片描述
整個搭建平臺核心模塊包含如下幾個部分:
3D場景渲染
組件拖拽系統
元素編輯功能
狀態管理
歷史記錄與撤銷/重做
技術棧
前端框架與庫
React 18
用于構建用戶界面的JavaScript庫
Next.js 14
React框架,提供服務端渲染、路由等功能
TypeScript
靜態類型檢查的JavaScript超集
Three.js
3D圖形庫,用于在瀏覽器中渲染3D場景
React Three Fiber
Three.js的React渲染器
React Three Drei
Three.js的React組件集合
Tailwind CSS
實用優先的CSS框架
Lucide React
現代圖標庫
狀態管理與工具
Zustand
輕量級狀態管理庫
UUID
用于生成唯一標識符
HTML5 Drag and Drop API
原生拖放功能實現
i3D Editor采用了組件化、模塊化的架構設計,主要分為以下幾個部分:

架構圖
在這里插入圖片描述
數據流
狀態管理
使用Zustand管理應用狀態,包括場景元素、選中元素等
用戶交互
用戶通過界面進行交互,如拖拽組件、選擇元素、調整屬性等
狀態更新
交互觸發狀態更新,通過Zustand的actions修改狀態
UI渲染
狀態變化觸發UI重新渲染,包括3D場景和編輯界面
歷史記錄
狀態變化被記錄到歷史棧中,支持撤銷/重做操作
核心功能實現
3D場景渲染
i3D Editor使用React Three Fiber和React Three Drei來簡化Three.js的使用,實現3D場景的渲染。

// Canvas設置
<Canvascamera={{ position: viewMode === "3D" ? [5, 5, 5] : [0, 5, 0], fov: 50 }}shadowsclassName="w-full h-full"
><ambientLight intensity={0.5} /><directionalLight position={[10, 10, 10]} intensity={1} castShadow />{/* 網格 */}<Gridargs={[100, 100]}cellSize={1}cellThickness={0.5}cellColor="#a0a0ff"sectionSize={5}sectionThickness={1}sectionColor="#2080ff"fadeDistance={50}fadeStrength={1.5}followCamera={false}infiniteGrid/>{/* 場景對象 */}{elements.map((element) => (<SceneObjectkey={element.id}element={element}isSelected={selectedElement?.id === element.id}onClick={() => setSelectedElement(element)}viewMode={viewMode}activeMode={activeMode}/>))}{/* 控制器 */}<OrbitControls makeDefault enabled={!selectedElement || activeMode !== "select"} /><Environment preset="studio" />
</Canvas>

組件拖拽系統
i3D Editor實現了一個基于HTML5 Drag and Drop API的拖拽系統,允許用戶從組件庫拖拽元素到3D場景中。


// 拖拽開始
const handleDragStart = (event, elementType) => {event.dataTransfer.setData("application/element-type", elementType);event.dataTransfer.effectAllowed = "copy";// 通知父組件拖拽開始onStartDrag(elementType);
};
// 拖拽結束
const handleDrop = (event) => {event.preventDefault();if (!isDragging || !draggedElementType) return;// 獲取Canvas容器的位置和尺寸const rect = canvasContainerRef.current.getBoundingClientRect();// 計算鼠標在Canvas中的相對位置const x = ((event.clientX - rect.left) / rect.width) * 2 - 1;const y = -((event.clientY - rect.top) / rect.height) * 2 + 1;// 創建射線并計算與平面的交點const raycaster = new THREE.Raycaster();raycaster.setFromCamera(new THREE.Vector2(x, y),new THREE.PerspectiveCamera(50, rect.width / rect.height, 0.1, 1000));const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);const target = new THREE.Vector3();raycaster.ray.intersectPlane(plane, target);// 添加元素到場景addElement({type: draggedElementType,position: { x: target.x, y: 0, z: target.z },rotation: { x: 0, y: 0, z: 0 },scale: 1,material: "standard",color: getDefaultColor(draggedElementType),name: getElementName(draggedElementType),displayTip: false,});// 重置拖拽狀態setIsDragging(false);setDraggedElementType(null);
};

元素編輯功能
i3D Editor提供了浮動工具欄,允許用戶對選中的元素進行編輯操作,如移動、旋轉、復制和刪除等。

// 浮動工具欄定位
<divref={toolbarRef}className={`absolute bg-white rounded-lg shadow-lg z-20 flex ${isHorizontalLayout ? "flex-row" : "flex-col"} items-center p-2`}style={{left: `${toolbarPosition.x}px`,top: `${toolbarPosition.y}px`,transform: "translate(-50%, -120%)",transition: "left 0.2s ease, top 0.2s ease",}}
>{/* 工具按鈕 */}<buttonclassName={`p-1.5 rounded-full hover:bg-blue-100 ${activeMode === "select" ? "text-blue-500" : ""}`}onClick={() => handleToolClick("select")}title="選擇工具"><MousePointer className="h-4 w-4" /></button>{/* 更多工具按鈕... */}
</div>

狀態管理實現
i3D Editor使用Zustand進行狀態管理,包括場景元素、選中元素等。


// 元素存儲
export const useElementStore = create<ElementStore>((set) => ({elements: [],selectedElement: null,addElement: (element) =>set((state) => ({elements: [...state.elements, { ...element, id: uuidv4() }],})),updateElement: (id, updates) =>set((state) => ({elements: state.elements.map((element) => element.id === id ? { ...element, ...updates } : element),selectedElement:state.selectedElement?.id === id ? { ...state.selectedElement, ...updates } : state.selectedElement,})),removeElement: (id) =>set((state) => ({elements: state.elements.filter((element) => element.id !== id),selectedElement: state.selectedElement?.id === id ? null : state.selectedElement,})),setSelectedElement: (element) => set({ selectedElement: element }),// 更多actions...
}));

i3D Editor實現了歷史記錄功能,支持撤銷和重做操作。


// 歷史記錄狀態
const [history, setHistory] = useState<HistoryState[]>([]);
const [historyIndex, setHistoryIndex] = useState(-1);
const [isUndoRedo, setIsUndoRedo] = useState(false);
// 監聽元素變化,更新歷史記錄
useEffect(() => {if (isUndoRedo) {setIsUndoRedo(false);return;}if (historyIndex >= 0) {const currentState: HistoryState = {elements: JSON.parse(JSON.stringify(elements)),selectedElementId: selectedElement?.id || null,};// 檢查是否與當前歷史記錄狀態相同const lastState = history[historyIndex];const isEqual =JSON.stringify(lastState.elements) === JSON.stringify(currentState.elements) &&lastState.selectedElementId === currentState.selectedElementId;if (!isEqual) {// 如果在歷史記錄中間進行了操作,則刪除后面的歷史記錄const newHistory = history.slice(0, historyIndex + 1);setHistory([...newHistory, currentState]);setHistoryIndex(historyIndex + 1);}}
}, [elements, selectedElement, history, historyIndex]);
// 撤銷操作
const handleUndo = () => {if (historyIndex > 0) {setIsUndoRedo(true);const prevState = history[historyIndex - 1];// 應用歷史狀態loadElements(prevState.elements);// 恢復選中狀態if (prevState.selectedElementId) {const selectedElement = prevState.elements.find((el) => el.id === prevState.selectedElementId);if (selectedElement) {setSelectedElement(selectedElement);}} else {setSelectedElement(null);}setHistoryIndex(historyIndex - 1);}
};
// 重做操作
const handleRedo = () => {if (historyIndex &lt; history.length - 1) {setIsUndoRedo(true);const nextState = history[historyIndex + 1];// 應用歷史狀態loadElements(nextState.elements);// 恢復選中狀態if (nextState.selectedElementId) {const selectedElement = nextState.elements.find((el) => el.id === nextState.selectedElementId);if (selectedElement) {setSelectedElement(selectedElement);}} else {setSelectedElement(null);}setHistoryIndex(historyIndex + 1);}
};

上面就是核心功能實現,當然項目還有很多需要優化,這里只是給大家提供一個方案思路參考,如果感興趣可以在github上下載代碼學習。

github地址:https://github.com/MrXujiang/3D-Editor

flowmix/docx多模態文檔引擎,目前也在持續更新中,歡迎體驗參考:https://flowmix.turntip.cn

多維表格 flowmix/mute

體驗地址:http://mute.turntip.cn

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

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

相關文章

“連接世界的橋梁:深入理解計算機網絡應用層”

一、引言 當你瀏覽網頁、發送郵件、聊天或觀看視頻時&#xff0c;這一切都離不開計算機網絡中的應用層&#xff08;Application Layer&#xff09;。 應用層是網絡協議棧的最頂層&#xff0c;直接為用戶的各種應用程序提供服務。它為用戶進程之間建立通信橋梁&#xff0c;屏蔽了…

JavaScript 代碼搜索框

1. 概述與需求分析 功能&#xff1a;在網頁中實時搜索用戶代碼、關鍵字&#xff1b;展示匹配行、文件名&#xff1b;支持高亮、正則、模糊匹配。非功能&#xff1a;大文件集&#xff08;幾十萬行&#xff09;、高并發、響應 <100ms&#xff1b;支持增量索引和熱更新。 2. …

【運維】Ubuntu apt 更新失敗?Temporary failure resolving ‘cn.archive.ubuntu.com‘ 問題

Ubuntu apt 更新失敗&#xff1f;Temporary failure resolving ‘cn.archive.ubuntu.com’ 問題 在使用 Ubuntu 時&#xff0c;你是否遇到過這樣一個煩人的錯誤&#xff1a; Temporary failure resolving ‘cn.archive.ubuntu.com’ 如果你也踩坑了&#xff0c;別慌&#xff0…

Uniapp:showLoading(等待加載)

目錄 一、出現場景二、效果展示三、具體使用一、出現場景 在項目的開發中,我們經常會請求后臺接口返回數據,但是每一個接口返回數據的時間不一致,有的快,有的慢,這個時候如果不加一個遮罩層,接口返回慢的時候,非常影響用戶體驗 二、效果展示 三、具體使用 顯示加載框…

【11408學習記錄】英語書信通知寫作模板大全:5個高分句式+使用場景解析,速存每日一句拆解練習!

書信/通知寫作錦囊妙句 英語寫作——19個錦囊妙句妙句9妙句10妙句11妙句12妙句13 每日一句詞匯第一步&#xff1a;找謂語第二步&#xff1a;斷句第三步&#xff1a;簡化讓步狀語從句限定性同位語從句主句 英語 寫作——19個錦囊妙句 妙句9 故宮在中國人民中很受歡迎/評價很高…

Unity 粒子同步,FishNet

Github的工程 同步畫面 使用FishNet插件同步&#xff0c;可使用這個選項來克隆第二個項目進行測試

【hadoop】案例:MapReduce批量寫入HBase

1.需求分析 我們仍然以美國各個氣象站每年的氣溫數據集為例&#xff0c;現在要求使用MapReduce讀取該數據集&#xff0c;然后批量寫入HBase數據庫&#xff0c;最后利用HBase shell根據行鍵即席查詢氣溫數據。 2.數據集準備 數據集的文件名為temperature.log&#xff0c;里面包含…

【linux網絡】網絡基礎概念

1. 初始協議 1.1 OSI 七層模型 OSI&#xff08;Open System Interconnection&#xff0c;開放系統互連&#xff09;七層網絡模型稱為開放式系統互聯參考模型&#xff0c;是一個邏輯上的定義和規范&#xff1b; 把網絡從邏輯上分為了 7 層. 每一層都有相關、相對應的物理設備&a…

【Android】談談DexClassLoader

一,Dex和Jar DEX 文件(Dalvik Executable)相較于普通的 JAR(Java 字節碼 .class 文件)進行了多方面的優化,主要是為了適應 Android 設備的性能和資源限制(例如內存、存儲空間和處理能力)。以下是 DEX 文件的一些具體優化點: 1. 內存占用優化 合并類文件: DEX 文件將…

【Flutter】Unity 三端封裝方案:Android / iOS / Web

關聯文檔&#xff1a;【方案分享】Flutter Unity 跨平臺三維渲染架構設計全解&#xff1a;插件封裝、通信機制與熱更新機制—— 支持 Android/iOS/Web 的 3D 內容嵌入與遠程資源管理&#xff0c;助力 XR 項目落地 —— 支持 Android/iOS/Web 的 3D 內容嵌入與遠程資源管理&…

Html1

一&#xff0c;HTML概述 網頁開發需要學習的知識&#xff1a; html css javaScript 兩個框架 VUE.js ElementUI UI user interface 用戶界面 HTML xml 可擴展標記語言-->存儲數據 Markup Language標簽語言都會提供各種標…

一、I/O的相關概念

I/O的相關概念 1、I/O I/O即Input和Output&#xff0c;用戶進程執行I/O操作&#xff0c;歸結起來&#xff0c;也就是向操作系統發出請求&#xff0c;讀請求就把數據填到緩沖區里&#xff0c;寫數據就把緩沖區里數據排干&#xff0c;目的地可以是磁盤也可以是其他通道。進程通…

出現Invalid bound statement (not found)問題的原因可能有哪些

1.全局配置文件沒配好&#xff1f; 檢查全局配置文件application.properties或application.yml是否配置掃描mapper包的文件路徑 #mybatis配置mapper文件路徑 #mybatis.mapper-locationsclasspath:/mapper/*.xml #mybatis-plus配置mapper文件路徑 mybatis-plus.mapper-locatio…

第十節:文本編輯

理論知識 文本編輯器的基本概念&#xff1a;文本編輯器是用于創建和編輯文本文件的工具。在 Linux 系統中&#xff0c;常見的文本編輯器有 vi、vim、nano 等。vi 和 vim 編輯器&#xff1a;vi 是一款經典的文本編輯器&#xff0c;vim 是 vi 的增強版&#xff0c;提供了更多的功…

部署一個自己的Spring Ai 服務(deepseek/通義千問)

Spring Boot 無縫接入 DeepSeek 和通義千問請求日志記錄及其ip黑白名單 SpringBoot版本 3.2.0 JDK 版本為17 redis 3.2.0 mybatis 3.0.3 依賴引入 關鍵依賴 <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-sp…

組裝 (DIY) 一臺顯示器 (4K 屏支持 4 畫面分屏 PBP 1080p x4)

首發日期 2025-04-26, 以下為原文內容: 家里的 PC 主機比較多, 如果同時開機, 顯示器就不夠用了. 因為窮, 窩租住的房間又很小, 放不下很多顯示器. 所以, 窩希望買一臺支持 分屏 功能的顯示器. 最好是 4K 分辨率 (3840x2160) 的屏幕, 然后 4 分屏 (有 4 個 DP 或 HDMI 輸入接口…

[Java入門]抽象類和接口

[Java入門]抽象類和接口 1. 抽象類1.1 抽象類的概念1.2 抽象類語法1.3 抽象類特性1.4 抽象類的作用 2. 接口2.1 接口的概念2.2 語法規則2.3 接口使用2.4 接口特性2.5 實現多個接口2.6 接口間的繼承2.7 抽象類和接口的區別 3. Object類3.1 獲取對象信息3.2 對象比較equals方法 1…

聚焦數字中國|AI賦能與安全守護:Coremail引領郵件辦公智能化轉型

4月28日&#xff0c;第八屆數字中國建設峰會在福州拉開序幕。當天&#xff0c;數字中國新產品新技術發布會開講&#xff0c;Coremail受邀亮相現場&#xff0c;與與會嘉賓分享AI在郵件產品領域的最新應用成果和實踐經驗。 Coremail首席客戶代表劉子建以《AI賦能與安全守護&#…

Qt官方案例知識點總結(拖放操作——Drag And Drop Robot )

-------------------------------------------------------------------------------------------------------------------------------- QPixmap輪廓剪裁 去掉Pixmap的外圍部分&#xff0c;如下&#xff1a; QPixmap pixmap("./img"); //調用createHeuristicMas…

【LLM】MOE混合專家大模型綜述(重要模塊原理)

note 當前的 MoE 架構就是一個用顯存換訓練時長/推理延遲的架構MoE 目前的架構基本集中在于將原先 GPT 每層的 FFN 復制多份作為 n 個 expert&#xff0c;并增加一個 router&#xff0c;用來計算每個 token 對應到哪個 FFN&#xff08;一般采用每個 token 固定指派 n 個 exper…