mirror of
				https://github.com/Tencent/tmagic-editor.git
				synced 2025-11-04 02:28:04 +08:00 
			
		
		
		
	feat(editor): 画布大小支持配置百分比
This commit is contained in:
		
							parent
							
								
									b0fcafd089
								
							
						
					
					
						commit
						eb43deb9f5
					
				@ -25,6 +25,8 @@
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
 | 
			
		||||
 | 
			
		||||
import { isNumber } from '@tmagic/utils';
 | 
			
		||||
 | 
			
		||||
import type { ScrollViewerEvent } from '@editor/type';
 | 
			
		||||
import { ScrollViewer } from '@editor/utils/scroll-viewer';
 | 
			
		||||
 | 
			
		||||
@ -36,8 +38,8 @@ defineOptions({
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(
 | 
			
		||||
  defineProps<{
 | 
			
		||||
    width?: number;
 | 
			
		||||
    height?: number;
 | 
			
		||||
    width?: number | string;
 | 
			
		||||
    height?: number | string;
 | 
			
		||||
    wrapWidth?: number;
 | 
			
		||||
    wrapHeight?: number;
 | 
			
		||||
    zoom?: number;
 | 
			
		||||
@ -63,8 +65,8 @@ const container = ref<HTMLDivElement>();
 | 
			
		||||
const el = ref<HTMLDivElement>();
 | 
			
		||||
const style = computed(
 | 
			
		||||
  () => `
 | 
			
		||||
        width: ${props.width}px;
 | 
			
		||||
        height: ${props.height}px;
 | 
			
		||||
        width: ${isNumber(`${props.width}`) ? `${props.width}px` : props.width};
 | 
			
		||||
        height: ${isNumber(`${props.height}`) ? `${props.height}px` : props.height};
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        margin-top: 30px;
 | 
			
		||||
      `,
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,8 @@
 | 
			
		||||
 | 
			
		||||
import { reactive } from 'vue';
 | 
			
		||||
 | 
			
		||||
import { convertToNumber } from '@tmagic/utils';
 | 
			
		||||
 | 
			
		||||
import editorService from '@editor/services/editor';
 | 
			
		||||
import type { StageRect, UiState } from '@editor/type';
 | 
			
		||||
 | 
			
		||||
@ -86,9 +88,12 @@ class Ui extends BaseService {
 | 
			
		||||
    const { height, width } = stageContainerRect;
 | 
			
		||||
    if (!width || !height) return 1;
 | 
			
		||||
 | 
			
		||||
    let stageWidth: number = convertToNumber(stageRect.width, width);
 | 
			
		||||
    let stageHeight: number = convertToNumber(stageRect.height, height);
 | 
			
		||||
 | 
			
		||||
    // 30为标尺的大小
 | 
			
		||||
    const stageWidth = stageRect.width + 30;
 | 
			
		||||
    const stageHeight = stageRect.height + 30;
 | 
			
		||||
    stageWidth = stageWidth + 30;
 | 
			
		||||
    stageHeight = stageHeight + 30;
 | 
			
		||||
 | 
			
		||||
    if (width > stageWidth && height > stageHeight) {
 | 
			
		||||
      return 1;
 | 
			
		||||
 | 
			
		||||
@ -173,8 +173,8 @@ export interface GetColumnWidth {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface StageRect {
 | 
			
		||||
  width: number;
 | 
			
		||||
  height: number;
 | 
			
		||||
  width: number | string;
 | 
			
		||||
  height: number | string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface UiState {
 | 
			
		||||
@ -185,7 +185,10 @@ export interface UiState {
 | 
			
		||||
  /** 画布显示放大倍数,默认为 1 */
 | 
			
		||||
  zoom: number;
 | 
			
		||||
  /** 画布容器的宽高 */
 | 
			
		||||
  stageContainerRect: StageRect;
 | 
			
		||||
  stageContainerRect: {
 | 
			
		||||
    width: number;
 | 
			
		||||
    height: number;
 | 
			
		||||
  };
 | 
			
		||||
  /** 画布顶层div的宽高,可用于改变画布的大小 */
 | 
			
		||||
  stageRect: StageRect;
 | 
			
		||||
  /** 编辑器列布局每一列的宽度,分为左中右三列 */
 | 
			
		||||
 | 
			
		||||
@ -398,3 +398,23 @@ export const getDefaultValueFromFields = (fields: DataSchema[]) => {
 | 
			
		||||
export const DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX = 'ds-field::';
 | 
			
		||||
 | 
			
		||||
export const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>;
 | 
			
		||||
 | 
			
		||||
export const calculatePercentage = (value: number, percentageStr: string) => {
 | 
			
		||||
  const percentage = globalThis.parseFloat(percentageStr) / 100; // 先将百分比字符串转换为浮点数,并除以100转换为小数
 | 
			
		||||
  const result = value * percentage;
 | 
			
		||||
  return result;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const isPercentage = (value: number | string) => /^(\d+)(\.\d+)?%$/.test(`${value}`);
 | 
			
		||||
 | 
			
		||||
export const convertToNumber = (value: number | string, parentValue = 0) => {
 | 
			
		||||
  if (typeof value === 'number') {
 | 
			
		||||
    return value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (typeof value === 'string' && isPercentage(value)) {
 | 
			
		||||
    return calculatePercentage(parentValue, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return parseFloat(value);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -7,24 +7,27 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { nextTick, ref } from 'vue';
 | 
			
		||||
import { computed, inject, nextTick, ref } from 'vue';
 | 
			
		||||
 | 
			
		||||
import Core from '@tmagic/core';
 | 
			
		||||
import { TMagicRadioButton, TMagicRadioGroup } from '@tmagic/design';
 | 
			
		||||
import { editorService } from '@tmagic/editor';
 | 
			
		||||
import type { Services } from '@tmagic/editor';
 | 
			
		||||
import { convertToNumber } from '@tmagic/utils';
 | 
			
		||||
 | 
			
		||||
import { DeviceType, uaMap } from '../const';
 | 
			
		||||
 | 
			
		||||
const devH: Record<DeviceType, number> = {
 | 
			
		||||
const services = inject<Services>('services');
 | 
			
		||||
 | 
			
		||||
const devH: Record<DeviceType, number | string> = {
 | 
			
		||||
  phone: 817,
 | 
			
		||||
  pad: 1024,
 | 
			
		||||
  pc: 900,
 | 
			
		||||
  pc: '100%',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const devW: Record<DeviceType, number> = {
 | 
			
		||||
const devW: Record<DeviceType, number | string> = {
 | 
			
		||||
  phone: 375,
 | 
			
		||||
  pad: 768,
 | 
			
		||||
  pc: 1600,
 | 
			
		||||
  pc: '100%',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getDeviceHeight = (viewerDevice: DeviceType) => devH[viewerDevice];
 | 
			
		||||
@ -48,15 +51,29 @@ withDefaults(
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['update:modelValue']);
 | 
			
		||||
 | 
			
		||||
const calcFontsize = (width: number) => {
 | 
			
		||||
  const iframe = editorService.get('stage')?.renderer.iframe;
 | 
			
		||||
const stageContainerRect = computed(() => services?.uiService.get('stageContainerRect'));
 | 
			
		||||
 | 
			
		||||
const calcFontsize = () => {
 | 
			
		||||
  if (!services) return;
 | 
			
		||||
 | 
			
		||||
  const iframe = services.editorService.get('stage')?.renderer.iframe;
 | 
			
		||||
  if (!iframe?.contentWindow) return;
 | 
			
		||||
 | 
			
		||||
  const app: Core = (iframe.contentWindow as any).appInstance;
 | 
			
		||||
 | 
			
		||||
  if (!app) return;
 | 
			
		||||
 | 
			
		||||
  app.setEnv(uaMap[viewerDevice.value]);
 | 
			
		||||
 | 
			
		||||
  app.setDesignWidth(app.env.isWeb ? width : 375);
 | 
			
		||||
  if (app.env.isWeb) {
 | 
			
		||||
    const stageRect = services.uiService.get('stageRect');
 | 
			
		||||
 | 
			
		||||
    const stageWidth: number = convertToNumber(stageRect.width, convertToNumber(stageContainerRect.value?.width || 0));
 | 
			
		||||
 | 
			
		||||
    app.setDesignWidth(stageWidth);
 | 
			
		||||
  } else {
 | 
			
		||||
    app.setDesignWidth(375);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const viewerDevice = ref(DeviceType.Phone);
 | 
			
		||||
@ -70,7 +87,7 @@ const deviceSelect = async (device: DeviceType) => {
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  await nextTick();
 | 
			
		||||
  calcFontsize(width);
 | 
			
		||||
  calcFontsize();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
defineExpose({
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user