This commit is contained in:
chndfang 2025-04-28 00:43:33 +08:00
parent 87db6f358c
commit 7ebf69cc2f
16 changed files with 84 additions and 29 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 902 B

BIN
public/point/11-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/point/12-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/point/13-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
public/point/14-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
public/point/15-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -56,6 +56,7 @@ export const EDITOR_CONFIG: Options = {
maxScale: 2.01, maxScale: 2.01,
scaleOff: 0.01, scaleOff: 0.01,
defaultAnchors: [], defaultAnchors: [],
activeGlobalAlpha: 0,
fontSize: 14, fontSize: 14,
lineHeight: 1.5, lineHeight: 1.5,
textAlign: 'center', textAlign: 'center',

View File

@ -4,6 +4,7 @@ import type { Pen } from '@meta2d/core';
import type { MapAreaType, MapPointType, MapRouteType } from './constant'; import type { MapAreaType, MapPointType, MapRouteType } from './constant';
export interface MapPen extends Pen { export interface MapPen extends Pen {
label?: string; // 展示名称
desc?: string; // 描述 desc?: string; // 描述
point?: MapPointInfo; // 点位信息 point?: MapPointInfo; // 点位信息

View File

@ -0,0 +1,17 @@
{
"color": "#BFBFBF",
"background": "#D9D9D9",
"point-s": {
"stroke": "#8C8C8C",
"strokeActive": "#FCC947",
"fill-1": "#14D1A5",
"fill-2": "#69C6F5",
"fill-3": "#E48B1D"
},
"point-l": {
"stroke": "#595959",
"strokeActive": "#FCC947",
"fill": "#1F1F1F"
},
"line": "#8C8C8C"
}

View File

@ -0,0 +1 @@
{}

View File

@ -1,12 +0,0 @@
{
"light": {
"background": "",
"color": "#000000"
},
"dark": {
"background": "",
"color": "#8C8C8C",
"activeColor": "#FCC947",
"textColor": "#BFBFBF"
}
}

View File

@ -21,7 +21,7 @@ const mode = ref<Mode>(Mode.常规);
watch(editor.value.mouseClick, (v) => { watch(editor.value.mouseClick, (v) => {
if (mode.value !== Mode.添加点位) return; if (mode.value !== Mode.添加点位) return;
if (isEmpty(v)) return; if (isEmpty(v)) return;
editor.value.addPoint(v); editor.value.addPoint(v, 11);
}); });
watch(editor.value.mouseBrush, (v) => { watch(editor.value.mouseBrush, (v) => {
if (![Mode.添加库区, Mode.添加互斥区, Mode.添加非互斥区].includes(mode.value)) return; if (![Mode.添加库区, Mode.添加互斥区, Mode.添加非互斥区].includes(mode.value)) return;

View File

@ -28,7 +28,7 @@ onMounted(() => {
<a-layout-content> <a-layout-content>
<div ref="container" class="full"></div> <div ref="container" class="full"></div>
</a-layout-content> </a-layout-content>
<a-layout-sider>sider</a-layout-sider> <a-layout-sider>{{ $t('查询') }}</a-layout-sider>
</a-layout> </a-layout>
</a-layout> </a-layout>
</template> </template>

View File

@ -2,8 +2,7 @@ import { EDITOR_CONFIG, MapAreaType, type MapPen, MapPointType } from '@api/map'
import sTheme from '@core/theme.service'; import sTheme from '@core/theme.service';
import { EditType, LockState, Meta2d } from '@meta2d/core'; import { EditType, LockState, Meta2d } from '@meta2d/core';
import { useObservable } from '@vueuse/rxjs'; import { useObservable } from '@vueuse/rxjs';
import THEME from 'asset/themes/editor.json'; import { cloneDeep, get, pick } from 'lodash-es';
import { cloneDeep, pick } from 'lodash-es';
import { debounceTime, filter, map, Subject, switchMap } from 'rxjs'; import { debounceTime, filter, map, Subject, switchMap } from 'rxjs';
import { watch } from 'vue'; import { watch } from 'vue';
@ -48,16 +47,27 @@ export class EditorService extends Meta2d {
//#region 点位 //#region 点位
public async addPoint(p: Point, type = MapPointType.): Promise<void> { public async addPoint(p: Point, type = MapPointType.): Promise<void> {
const pen: MapPen = { const pen: MapPen = {
...p,
...this.#mapPoint(type),
name: 'point', name: 'point',
x: p.x, text: 'POINT',
y: p.y,
width: 24,
height: 24,
point: { type }, point: { type },
}; };
const { x, y, width, height } = this.getPenRect(pen);
pen.x = x - width / 2;
pen.y = y - height / 2;
await this.addPen(pen, false, true, true); await this.addPen(pen, false, true, true);
this.pushHistory({ type: EditType.Add, pens: [cloneDeep(pen)] }); this.pushHistory({ type: EditType.Add, pens: [cloneDeep(pen)] });
} }
#mapPoint(type: MapPointType): Required<Pick<MapPen, 'width' | 'height' | 'lineWidth' | 'image'>> {
const theme = this.data().theme;
const width = type < 10 ? 24 : 48;
const height = type < 10 ? 24 : 60;
const lineWidth = type < 10 ? 2 : 3;
const image = type < 10 ? '' : `/point/${type}-${theme}.png`;
return { width, height, lineWidth, image };
}
//#endregion //#endregion
//#region 线路 //#region 线路
@ -114,7 +124,6 @@ export class EditorService extends Meta2d {
} }
#register() { #register() {
this.store.theme = THEME;
this.registerCanvasDraw({ point: drawPoint, line: drawLine, area: drawArea }); this.registerCanvasDraw({ point: drawPoint, line: drawLine, area: drawArea });
this.registerAnchors({ point: anchorPoint }); this.registerAnchors({ point: anchorPoint });
} }
@ -122,14 +131,40 @@ export class EditorService extends Meta2d {
//#region 绘制函数 //#region 绘制函数
function drawPoint(ctx: CanvasRenderingContext2D, pen: MapPen): void { function drawPoint(ctx: CanvasRenderingContext2D, pen: MapPen): void {
const theme = sTheme.editor;
const active = pen.calculative?.active;
const { x = 0, y = 0, width = 0, height = 0 } = pen.calculative?.worldRect ?? {}; const { x = 0, y = 0, width = 0, height = 0 } = pen.calculative?.worldRect ?? {};
const { type } = pen.point ?? {}; const { type } = pen.point ?? {};
const { label = '' } = pen ?? {};
ctx.save(); ctx.save();
ctx.lineWidth = 2; switch (type) {
ctx.roundRect(x, y, width, height, 4); case MapPointType.:
ctx.stroke(); case MapPointType.:
ctx.fillStyle = '#fff'; case MapPointType.:
ctx.fillText(String(type), x + width / 2, y + height / 2); case MapPointType.:
ctx.lineWidth = 2;
break;
case MapPointType.:
case MapPointType.:
case MapPointType.:
case MapPointType.:
case MapPointType.:
ctx.rect(x, y, width, height);
// ctx.fillStyle = get(theme, 'point-l.fill') ?? '';
// ctx.fill();
ctx.strokeStyle = get(theme, active ? 'point-l.strokeActive' : 'point-l.stroke') ?? '';
ctx.stroke();
break;
default:
break;
}
ctx.fillStyle = get(theme, 'color') ?? '';
ctx.font = '14px/20px system-ui';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(label, x + width / 2, y - 10);
ctx.restore(); ctx.restore();
} }
function anchorPoint(pen: MapPen): void { function anchorPoint(pen: MapPen): void {

View File

@ -22,8 +22,9 @@ enum Locale {
export const LOCALES = Object.freeze<[string, Locale][]>(Object.entries(Locale)); export const LOCALES = Object.freeze<[string, Locale][]>(Object.entries(Locale));
export const i18n = createI18n({ export const i18n = createI18n({
legacy: true, legacy: false,
silentTranslationWarn: true, missingWarn: false,
fallbackWarn: false,
locale: Locale.简体中文, locale: Locale.简体中文,
messages: chain(Locale) messages: chain(Locale)
.invert() .invert()
@ -58,7 +59,7 @@ class LocaleService {
} }
#load(locale: Locale): void { #load(locale: Locale): void {
i18n.global.locale = locale; i18n.global.locale.value = locale;
switch (locale) { switch (locale) {
case Locale.English: case Locale.English:
dayjs.locale('en'); dayjs.locale('en');

View File

@ -1,6 +1,13 @@
import { theme, type TokenType as AntdTheme } from 'ant-design-vue'; import { theme, type TokenType as AntdTheme } from 'ant-design-vue';
import { chain } from 'lodash-es';
import { ref, watch } from 'vue'; import { ref, watch } from 'vue';
const THEME_FILES = import.meta.glob('asset/themes/*.json', { eager: true, import: 'default' });
const THEME_MAP = chain(THEME_FILES)
.mapKeys((_, k) => k.match(/^.*[\\|\\/](.+?)\.[^\\.]+$/)?.[1])
.mapValues((v) => <Record<string, string>>v)
.value();
enum Theme { enum Theme {
Light = 'light', Light = 'light',
Dark = 'dark', Dark = 'dark',
@ -29,6 +36,10 @@ class ThemeService {
} }
} }
public get editor(): object {
return THEME_MAP[`editor-${this.#theme.value}`] ?? {};
}
constructor() { constructor() {
watch(this.#theme, (v) => this.#load(v), { immediate: true }); watch(this.#theme, (v) => this.#load(v), { immediate: true });
} }