diff --git a/packages/editor/src/components/header/navigation/Copy.vue b/packages/editor/src/components/header/navigation/Copy.vue index 4c492cb..5410d85 100644 --- a/packages/editor/src/components/header/navigation/Copy.vue +++ b/packages/editor/src/components/header/navigation/Copy.vue @@ -18,7 +18,7 @@ import {onMounted, ref} from "vue"; import {Copy} from "@vicons/carbon"; import {NIcon, NTooltip} from "naive-ui"; import {t} from "@/language"; -import {App,Hooks,AddObjectCommand} from "@astral3d/engine"; +import {App,Hooks,Loader,Utils,AddObjectCommand} from "@astral3d/engine"; const disabled = ref(true); @@ -36,6 +36,15 @@ function handleClone() { //避免复制相机或场景 if (object === null || object.parent === null) return; + if (Utils.isHtmlPanelObject(object)) { + const _json = object.toJSON() as any; + + Loader.objectLoader.parseAsync(_json).then(newObject3D => { + App.execute(new AddObjectCommand(newObject3D)); + }).catch((e: Error) => window.$message?.error(e.message)); + return; + } + object = object.clone(); App.execute(new AddObjectCommand(object)); diff --git a/packages/editor/src/components/tree/SceneTree.vue b/packages/editor/src/components/tree/SceneTree.vue index ea72d9d..1de6119 100644 --- a/packages/editor/src/components/tree/SceneTree.vue +++ b/packages/editor/src/components/tree/SceneTree.vue @@ -19,7 +19,7 @@ import { ChoroplethMap } from '@vicons/carbon'; import {t} from "@/language"; -import {App,Hooks, MoveObjectCommand, RemoveObjectCommand, AddObjectCommand} from "@astral3d/engine"; +import {App,Hooks,Loader,Utils, MoveObjectCommand, RemoveObjectCommand, AddObjectCommand} from "@astral3d/engine"; import {escapeHTML, findSiblingsAndIndex} from "@/utils/common/utils"; import {getMaterialName} from "@/utils/common/scenes"; import EsContextmenu from "@/components/es/EsContextmenu.vue"; @@ -367,6 +367,15 @@ function handleContextmenuSelect(key: string) { if (parent !== null) App.execute(new RemoveObjectCommand(object)); break; case "clone": + if (Utils.isHtmlPanelObject(object)) { + const _json = object.toJSON() as any; + + Loader.objectLoader.parseAsync(_json).then(newObject3D => { + App.execute(new AddObjectCommand(newObject3D)); + }).catch((e: Error) => window.$message?.error(e.message)); + break; + } + const _object = object.clone(); App.execute(new AddObjectCommand(_object)); diff --git a/packages/editor/src/views/editor/layouts/sidebar/SidebarHtmlPanel.vue b/packages/editor/src/views/editor/layouts/sidebar/SidebarHtmlPanel.vue index 2f1bcdc..3072e82 100644 --- a/packages/editor/src/views/editor/layouts/sidebar/SidebarHtmlPanel.vue +++ b/packages/editor/src/views/editor/layouts/sidebar/SidebarHtmlPanel.vue @@ -29,6 +29,22 @@ onBeforeUnmount(() => { Hooks.useRemoveSignal("objectSelected", updateUI); }) +function ensureHtmlPanelOptions(object: any) { + const options = object?.options || {}; + const codes = Array.isArray(options.codes) ? options.codes : []; + const isSingleHtml = typeof options.isSingleHtml === 'boolean' ? options.isSingleHtml : true; + const isSprite = typeof options.isSprite === 'boolean' ? options.isSprite : !!object?.isHtmlSprite; + + object.options = { + ...options, + codes, + isSingleHtml, + isSprite + }; + + return object.options; +} + function updateUI() { const object = App.selected; if(!object) return; @@ -39,7 +55,8 @@ function updateUI() { } data.type = object.isHtmlPanel? 'panel' :'sprite'; - data.codes = object.options.codes; + const options = ensureHtmlPanelOptions(object); + data.codes = options.codes; } function update(method: string){ @@ -55,6 +72,7 @@ function update(method: string){ const _json = object.toJSON() as any; _json.object.type = data.type === 'panel' ? 'HtmlSprite' : 'HtmlPanel'; + _json.object.options = _json.object.options || {}; _json.object.options.isSprite = !_json.object.options.isSprite; Loader.objectLoader.parseAsync(_json).then(newObject3D => { @@ -73,9 +91,11 @@ function update(method: string){ _code.content = editorCode.code; + const options = ensureHtmlPanelOptions(object); + const htmlPanelOption = { - isSprite: object.options.isSprite, - isSingleHtml:object.options.isSingleHtml, + isSprite: options.isSprite, + isSingleHtml: options.isSingleHtml, codes: data.codes } @@ -135,10 +155,12 @@ function updateFileList(fList: UploadFileInfo[]) { isSprite: data.type ==='sprite', fileName: file.name }).then(htmlPlaneObj => { - object.options.codes = htmlPlaneObj.options.codes; - object.options.isSingleHtml = htmlPlaneObj.options.isSingleHtml; + const options = ensureHtmlPanelOptions(object); - data.codes = object.options.codes; + options.codes = htmlPlaneObj.options.codes; + options.isSingleHtml = htmlPlaneObj.options.isSingleHtml; + + data.codes = options.codes; // Keep object identity (id/uuid) so scene tree and context menu references stay valid. while (object.element.firstChild) { diff --git a/packages/editor/src/views/home/dataCenter/DataSet.vue b/packages/editor/src/views/home/dataCenter/DataSet.vue index 82c17dc..b8a2a6b 100644 --- a/packages/editor/src/views/home/dataCenter/DataSet.vue +++ b/packages/editor/src/views/home/dataCenter/DataSet.vue @@ -1,5 +1,5 @@ \ No newline at end of file