/* * Tencent is pleased to support the open source community by making TMagicEditor available. * * Copyright (C) 2023 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 editorService from '@editor/services/editor'; import type { StageRect, UiState } from '@editor/type'; import BaseService from './BaseService'; const state = reactive({ 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, floatBox: new Map(), hideSlideBar: false, }); class Ui extends BaseService { constructor() { super(['zoom', 'calcZoom']); } public set(name: K, value: T) { const mask = editorService.get('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[name] = value; } public get(name: K) { return state[name]; } public async zoom(zoom: number) { this.set('zoom', (this.get('zoom') * 100 + zoom * 100) / 100); if (this.get('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 async setFloatBox(keys: string[]) { const map = state.floatBox; for (const key of keys) { if (map.get(key)) continue; map.set(key, { status: false, zIndex: 99, top: 0, left: 0, }); } } 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();