web-map/src/services/editor.service.ts

91 lines
2.1 KiB
TypeScript
Raw Normal View History

2025-04-20 00:49:14 +08:00
import { EDITOR_CONFIG, type MapPen, MapPointType } from '@api/map';
import sTheme from '@core/theme.service';
import { LockState, Meta2d } from '@meta2d/core';
import THEME from 'asset/themes/editor.json';
import { watch } from 'vue';
export class EditorService {
readonly #editor: Meta2d;
public destroy() {
this.#editor.destroy();
}
public resize(): void {
this.#editor.resize();
this.#editor.render();
}
public open(map?: string, readonly = false): void {
const data = map ? JSON.parse(map) : undefined;
this.#editor.open(data);
this.#editor.lock(readonly ? LockState.Disable : LockState.None);
}
public save(): string {
const data = this.#editor.data();
const map = JSON.stringify(data);
return map;
}
public export(): string {
const png = this.#editor.toPng(10);
return png;
}
//#region 点位
public async addPoint(x: number = 0, y: number = 0, type = MapPointType.): Promise<void> {
const pen: MapPen = {
name: 'point',
x,
y,
width: 24,
height: 24,
point: { type },
};
await this.#editor.addPen(pen);
}
//#endregion
//#region 线路
//#endregion
//#region 区域
//#endregion
constructor(container: HTMLDivElement) {
this.#editor = new Meta2d(container, EDITOR_CONFIG);
(<HTMLDivElement>container.children.item(5)).ondrop = null;
this.#editor.on('*', (e, v) => this.#listen(e, v));
this.#register();
watch(
() => sTheme.theme,
(v) => this.#editor.setTheme(v),
{ immediate: true },
);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
#listen(e: unknown, v: any) {
switch (e) {
default:
// console.log(e, v);
break;
}
}
#register() {
this.#editor.store.theme = THEME;
this.#editor.registerCanvasDraw({ point: drawPoint });
}
}
//#region 绘制函数
function drawPoint(ctx: CanvasRenderingContext2D, pen: MapPen): void {
const { x = 0, y = 0, width = 0, height = 0 } = pen.calculative?.worldRect ?? {};
const { type } = pen.point ?? {};
ctx.rect(x, y, width, height);
ctx.stroke();
}
//#endregion