/* * 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, toRaw } from 'vue'; import type StageCore from '@tmagic/stage'; import editorService from '@editor/services/editor'; import type { GetColumnWidth, SetColumnWidth, StageRect, UiState } from '@editor/type'; import BaseService from './BaseService'; const DEFAULT_LEFT_COLUMN_WIDTH = 310; const DEFAULT_RIGHT_COLUMN_WIDTH = 480; const COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorColumnWidthData'; const defaultColumnWidth = { left: DEFAULT_LEFT_COLUMN_WIDTH, center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH, right: DEFAULT_RIGHT_COLUMN_WIDTH, }; const state = reactive({ uiSelectMode: false, showSrc: false, zoom: 1, stageContainerRect: { width: 0, height: 0, }, stageRect: { width: 375, height: 817, }, columnWidth: defaultColumnWidth, showGuides: true, showRule: true, propsPanelSize: 'small', }); class Ui extends BaseService { constructor() { super([]); globalThis.addEventListener('resize', () => { this.setColumnWidth({ center: 'auto', }); }); const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY); if (columnWidthCacheData) { try { const columnWidthCache = JSON.parse(columnWidthCacheData); this.setColumnWidth(columnWidthCache); } catch (e) { console.error(e); } } } public set(name: keyof UiState, value: T) { const mask = editorService.get('stage')?.mask; if (name === 'columnWidth') { this.setColumnWidth(value as unknown as SetColumnWidth); return; } 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; if (name === 'stageContainerRect') { state.zoom = this.calcZoom(); } } public get(name: keyof typeof state): T { return (state as any)[name]; } public zoom(zoom: number) { this.set('zoom', (this.get('zoom') * 100 + zoom * 100) / 100); if (this.get('zoom') < 0.1) this.set('zoom', 0.1); } private setColumnWidth({ left, center, right }: SetColumnWidth) { const columnWidth = { ...toRaw(this.get('columnWidth')), }; if (left) { columnWidth.left = left; } if (right) { columnWidth.right = right; } if (!center || center === 'auto') { const bodyWidth = globalThis.document.body.clientWidth; columnWidth.center = bodyWidth - (columnWidth?.left || 0) - (columnWidth?.right || 0); if (columnWidth.center <= 0) { columnWidth.left = defaultColumnWidth.left; columnWidth.center = defaultColumnWidth.center; columnWidth.right = defaultColumnWidth.right; } } else { columnWidth.center = center; } globalThis.localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(columnWidth)); state.columnWidth = columnWidth; } private setStageRect(value: StageRect) { state.stageRect = { ...state.stageRect, ...value, }; state.zoom = this.calcZoom(); } private calcZoom() { const { stageRect, stageContainerRect } = state; const { height, width } = stageContainerRect; if (!width || !height) return 1; if (width > stageRect.width && height > stageRect.height) { return 1; } return Math.min((width - 100) / stageRect.width || 1, (height - 100) / stageRect.height || 1); } } export type UiService = Ui; export default new Ui();