mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-06-17 10:35:11 +08:00
128 lines
3.1 KiB
TypeScript
128 lines
3.1 KiB
TypeScript
/*
|
||
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
||
*
|
||
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
*/
|
||
|
||
import { reactive } from 'vue';
|
||
|
||
import type StageCore from '@tmagic/stage';
|
||
|
||
import editorService from '../services/editor';
|
||
import type { StageRect, UiState } from '../type';
|
||
|
||
import BaseService from './BaseService';
|
||
|
||
const state = reactive<UiState>({
|
||
uiSelectMode: false,
|
||
showSrc: false,
|
||
zoom: 1,
|
||
stageContainerRect: {
|
||
width: 0,
|
||
height: 0,
|
||
},
|
||
stageRect: {
|
||
width: 375,
|
||
height: 817,
|
||
},
|
||
columnWidth: {
|
||
left: 0,
|
||
right: 0,
|
||
center: 0,
|
||
},
|
||
showGuides: true,
|
||
showRule: true,
|
||
propsPanelSize: 'small',
|
||
showAddPageButton: true,
|
||
});
|
||
|
||
class Ui extends BaseService {
|
||
constructor() {
|
||
super(['zoom', 'calcZoom']);
|
||
}
|
||
|
||
public set<T = any>(name: keyof UiState, value: T) {
|
||
const mask = editorService.get<StageCore>('stage')?.mask;
|
||
|
||
if (name === 'stageRect') {
|
||
this.setStageRect(value as unknown as StageRect);
|
||
return;
|
||
}
|
||
|
||
if (name === 'showGuides') {
|
||
mask?.showGuides(value as unknown as boolean);
|
||
}
|
||
|
||
if (name === 'showRule') {
|
||
mask?.showRule(value as unknown as boolean);
|
||
}
|
||
|
||
(state as any)[name] = value;
|
||
}
|
||
|
||
public get<T>(name: keyof typeof state): T {
|
||
return (state as any)[name];
|
||
}
|
||
|
||
public async zoom(zoom: number) {
|
||
this.set('zoom', (this.get<number>('zoom') * 100 + zoom * 100) / 100);
|
||
if (this.get<number>('zoom') < 0.1) this.set('zoom', 0.1);
|
||
}
|
||
|
||
public async calcZoom() {
|
||
const { stageRect, stageContainerRect } = state;
|
||
const { height, width } = stageContainerRect;
|
||
if (!width || !height) return 1;
|
||
|
||
// 30为标尺的大小
|
||
const stageWidth = stageRect.width + 30;
|
||
const stageHeight = stageRect.height + 30;
|
||
|
||
if (width > stageWidth && height > stageHeight) {
|
||
return 1;
|
||
}
|
||
// 60/80是为了不要让画布太过去贴住四周(这样好看些)
|
||
return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
|
||
}
|
||
|
||
public resetState() {
|
||
this.set('showSrc', false);
|
||
this.set('uiSelectMode', false);
|
||
this.set('zoom', 1);
|
||
this.set('stageContainerRect', {
|
||
width: 0,
|
||
height: 0,
|
||
});
|
||
}
|
||
|
||
public destroy() {
|
||
this.resetState();
|
||
this.removeAllListeners();
|
||
this.removeAllPlugins();
|
||
}
|
||
|
||
private async setStageRect(value: StageRect) {
|
||
state.stageRect = {
|
||
...state.stageRect,
|
||
...value,
|
||
};
|
||
state.zoom = await this.calcZoom();
|
||
}
|
||
}
|
||
|
||
export type UiService = Ui;
|
||
|
||
export default new Ui();
|