1
0
mirror of synced 2026-04-18 01:59:36 +08:00

feat(stage): 支持将指定id的dom生成图片

This commit is contained in:
roymondchen
2026-04-09 15:05:41 +08:00
parent 6e07d5762b
commit b3f4e42716
4 changed files with 56 additions and 0 deletions

View File

@@ -31,6 +31,7 @@
"dependencies": {
"@scena/guides": "^0.29.2",
"events": "^3.3.0",
"@zumer/snapdom": "^2.8.0",
"keycon": "^1.4.0",
"lodash-es": "^4.17.21",
"moveable": "^0.53.0",

View File

@@ -18,6 +18,7 @@
import { EventEmitter } from 'events';
import { SnapdomOptions } from '@zumer/snapdom';
import type { MoveableOptions, OnDragStart } from 'moveable';
import type { Id } from '@tmagic/core';
@@ -272,6 +273,21 @@ export default class StageCore extends EventEmitter {
this.renderer?.reloadIframe(url);
}
/**
* 将指定id的dom元素生成为图片
*/
public async getElementImage(
id: Id,
type: 'download' | 'raw' | 'svg' | 'canvas' | 'png' | 'jpeg' | 'webp' | 'blob' = 'png',
options: SnapdomOptions = {},
) {
if (!this.renderer) {
throw new Error('Renderer is not initialized');
}
return this.renderer.getElementImage(id, type, options);
}
/**
* 销毁实例
*/

View File

@@ -18,6 +18,8 @@
import { EventEmitter } from 'events';
import { snapdom, SnapdomOptions } from '@zumer/snapdom';
import type { Id } from '@tmagic/core';
import { getElById, getHost, guid, injectStyle, isSameDomain } from '@tmagic/core';
@@ -162,6 +164,35 @@ export default class StageRender extends EventEmitter {
return getElById()(this.getDocument(), id);
}
/**
* 将指定id的dom元素生成为图片
* @param id 目标元素的id
* @param options 图片生成选项
* @returns data URL 格式的图片数据
*/
public async getElementImage(
id: Id,
type: 'download' | 'raw' | 'svg' | 'canvas' | 'png' | 'jpeg' | 'webp' | 'blob' = 'png',
options: SnapdomOptions = {},
) {
const el = this.getTargetElement(id);
if (!el) {
throw new Error(`Element with id "${id}" not found`);
}
el.scrollIntoView();
const toFunc = `to${type.charAt(0).toUpperCase() + type.slice(1)}`;
const result = await snapdom(el, options);
if (toFunc in result) {
return result[toFunc]();
}
throw new Error(`Invalid type: ${type}`);
}
public postTmagicRuntimeReady() {
this.contentWindow = this.iframe?.contentWindow as RuntimeWindow;

8
pnpm-lock.yaml generated
View File

@@ -460,6 +460,9 @@ importers:
'@tmagic/core':
specifier: workspace:*
version: link:../core
'@zumer/snapdom':
specifier: ^2.8.0
version: 2.8.0
events:
specifier: ^3.3.0
version: 3.3.0
@@ -3652,6 +3655,9 @@ packages:
'@vueuse/shared@9.13.0':
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
'@zumer/snapdom@2.8.0':
resolution: {integrity: sha512-NhztgFDNfOkFt8Ox9PIJ1IwggyMui5UDazysOgZD7FSGL0G7H8U+J3ft0iecxAS8daj5aC62i3blaTk7s2GcpA==}
JSONStream@1.3.5:
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
hasBin: true
@@ -9482,6 +9488,8 @@ snapshots:
- '@vue/composition-api'
- vue
'@zumer/snapdom@2.8.0': {}
JSONStream@1.3.5:
dependencies:
jsonparse: 1.3.1