From 1339b50e55a9c1d1c6647f22b888fec04de8796f Mon Sep 17 00:00:00 2001 From: nighca Date: Sun, 29 Sep 2024 18:01:46 +0800 Subject: [PATCH] take screenshot with StageViewer --- .../preview/stage-viewer/NodeTransformer.vue | 9 +++++++ .../preview/stage-viewer/StageViewer.vue | 23 +++++++++++++++++- spx-gui/src/models/project/index.ts | 24 ++++++++++++++----- spx-gui/src/utils/utils.ts | 7 +++++- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/spx-gui/src/components/editor/preview/stage-viewer/NodeTransformer.vue b/spx-gui/src/components/editor/preview/stage-viewer/NodeTransformer.vue index 15df133ba..6d7a7321e 100644 --- a/spx-gui/src/components/editor/preview/stage-viewer/NodeTransformer.vue +++ b/spx-gui/src/components/editor/preview/stage-viewer/NodeTransformer.vue @@ -47,4 +47,13 @@ effect(async () => { await nextTick() // Wait to ensure the selected node updated by Konva transformerNode.nodes([selectedNode]) }) + +defineExpose({ + withHidden(callback: () => T): T { + transformer.value?.getNode().hide() + const ret = callback() + transformer.value?.getNode().show() + return ret + } +}) diff --git a/spx-gui/src/components/editor/preview/stage-viewer/StageViewer.vue b/spx-gui/src/components/editor/preview/stage-viewer/StageViewer.vue index d4b983a38..8730b6bde 100644 --- a/spx-gui/src/components/editor/preview/stage-viewer/StageViewer.vue +++ b/spx-gui/src/components/editor/preview/stage-viewer/StageViewer.vue @@ -29,7 +29,7 @@ /> - + @@ -52,9 +52,11 @@ import type { Stage } from 'konva/lib/Stage' import { UIDropdown, UILoading, UIMenu, UIMenuItem } from '@/components/ui' import { useContentSize } from '@/utils/dom' import { useFileUrl } from '@/utils/file' +import { until, untilNotNull } from '@/utils/utils' import type { Sprite } from '@/models/sprite' import { MapMode } from '@/models/stage' import type { Widget } from '@/models/widget' +import { createFileWithWebUrl } from '@/models/common/cloud' import { useEditorCtx } from '../../EditorContextProvider.vue' import NodeTransformer from './NodeTransformer.vue' import SpriteNode from './SpriteNode.vue' @@ -69,6 +71,7 @@ const stageRef = ref<{ getStage(): Konva.Stage }>() const mapSize = computed(() => editorCtx.project.stage.getMapSize()) +const nodeTransformerRef = ref>() const nodeReadyMap = reactive(new Map()) @@ -239,6 +242,24 @@ async function moveZorder(direction: 'up' | 'down' | 'top' | 'bottom') { }) menuVisible.value = false } + +async function takeScreenshot(name: string) { + const stage = await untilNotNull(stageRef) + const nodeTransformer = await untilNotNull(nodeTransformerRef) + await until(() => !loading.value) + // Omit transform control when taking screenshot + const dataUrl = nodeTransformer.withHidden(() => + stage.getStage().toDataURL({ + mimeType: 'image/jpeg' + }) + ) + return createFileWithWebUrl(dataUrl, `${name}.jpg`) +} + +watchEffect((onCleanup) => { + const unbind = editorCtx.project.bindScreenshotTaker(takeScreenshot) + onCleanup(unbind) +})