fix(playground,runtime): 设备切换时,重新设置root font size与ua

fix #501
This commit is contained in:
roymondchen 2023-04-10 16:42:22 +08:00
parent 3d9f38781a
commit 84e2cdf22d
15 changed files with 120 additions and 71 deletions

View File

@ -13,6 +13,7 @@
}, },
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "^2.0.9", "@element-plus/icons-vue": "^2.0.9",
"@tmagic/core": "1.2.13",
"@tmagic/design": "1.2.13", "@tmagic/design": "1.2.13",
"@tmagic/editor": "1.2.13", "@tmagic/editor": "1.2.13",
"@tmagic/element-plus-adapter": "1.2.13", "@tmagic/element-plus-adapter": "1.2.13",

View File

@ -6,16 +6,13 @@
</el-radio-group> </el-radio-group>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, ref } from 'vue'; import { nextTick, ref } from 'vue';
import Core from '@tmagic/core';
import { editorService } from '@tmagic/editor'; import { editorService } from '@tmagic/editor';
enum DeviceType { import { DeviceType, uaMap } from '../const';
Phone = 'phone',
Pad = 'pad',
PC = 'pc',
}
const devH: Record<DeviceType, number> = { const devH: Record<DeviceType, number> = {
phone: 817, phone: 817,
@ -33,32 +30,37 @@ const getDeviceHeight = (viewerDevice: DeviceType) => devH[viewerDevice];
const getDeviceWidth = (viewerDevice: DeviceType) => devW[viewerDevice]; const getDeviceWidth = (viewerDevice: DeviceType) => devW[viewerDevice];
export default defineComponent({ withDefaults(
props: { defineProps<{
modelValue: { modelValue: {
type: Object, width: number;
default: () => ({ height: number;
};
}>(),
{
modelValue: () => ({
width: 375, width: 375,
height: 817, height: 817,
}), }),
}, },
}, );
emits: ['update:modelValue'], const emit = defineEmits(['update:modelValue']);
setup(props, { emit }) {
const calcFontsize = (width: number) => { const calcFontsize = (width: number) => {
const iframe = editorService.get('stage')?.renderer.iframe; const iframe = editorService.get('stage')?.renderer.iframe;
if (!iframe?.contentWindow) return; if (!iframe?.contentWindow) return;
iframe.contentWindow.appInstance.designWidth = width;
const app: Core = (iframe.contentWindow as any).appInstance;
app.setEnv(uaMap[viewerDevice.value]);
app.setDesignWidth(app.env.isWeb ? width : 375);
}; };
const viewerDevice = ref(DeviceType.Phone); const viewerDevice = ref(DeviceType.Phone);
return { const deviceSelect = async (device: DeviceType) => {
viewerDevice,
deviceSelect(device: DeviceType) {
const width = getDeviceWidth(device); const width = getDeviceWidth(device);
const height = getDeviceHeight(device); const height = getDeviceHeight(device);
emit('update:modelValue', { emit('update:modelValue', {
@ -66,10 +68,12 @@ export default defineComponent({
height, height,
}); });
await nextTick();
calcFontsize(width); calcFontsize(width);
},
}; };
},
defineExpose({
viewerDevice,
}); });
</script> </script>

14
playground/src/const.ts Normal file
View File

@ -0,0 +1,14 @@
export enum DeviceType {
Phone = 'phone',
Pad = 'pad',
PC = 'pc',
}
export const uaMap = {
[DeviceType.Phone]:
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1',
[DeviceType.Pad]:
'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
[DeviceType.PC]:
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
};

View File

@ -15,7 +15,7 @@
:stage-rect="stageRect" :stage-rect="stageRect"
> >
<template #workspace-content> <template #workspace-content>
<DeviceGroup v-model="stageRect"></DeviceGroup> <DeviceGroup ref="deviceGroup" v-model="stageRect"></DeviceGroup>
</template> </template>
</m-editor> </m-editor>
@ -26,13 +26,19 @@
title="预览" title="预览"
:width="stageRect && stageRect.width" :width="stageRect && stageRect.width"
> >
<iframe v-if="previewVisible" width="100%" :height="stageRect && stageRect.height" :src="previewUrl"></iframe> <iframe
v-if="previewVisible"
ref="iframe"
width="100%"
:height="stageRect && stageRect.height"
:src="previewUrl"
></iframe>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref, toRaw } from 'vue'; import { computed, nextTick, ref, toRaw } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { Coin, Connection, Document } from '@element-plus/icons-vue'; import { Coin, Connection, Document } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
@ -47,12 +53,15 @@ import { asyncLoadJs } from '@tmagic/utils';
import DeviceGroup from '../components/DeviceGroup.vue'; import DeviceGroup from '../components/DeviceGroup.vue';
import componentGroupList from '../configs/componentGroupList'; import componentGroupList from '../configs/componentGroupList';
import dsl from '../configs/dsl'; import dsl from '../configs/dsl';
import { uaMap } from '../const';
const { VITE_RUNTIME_PATH, VITE_ENTRY_PATH } = import.meta.env; const { VITE_RUNTIME_PATH, VITE_ENTRY_PATH } = import.meta.env;
const runtimeUrl = `${VITE_RUNTIME_PATH}/playground/index.html`; const runtimeUrl = `${VITE_RUNTIME_PATH}/playground/index.html`;
const router = useRouter(); const router = useRouter();
const editor = ref<InstanceType<typeof TMagicEditor>>(); const editor = ref<InstanceType<typeof TMagicEditor>>();
const deviceGroup = ref<InstanceType<typeof DeviceGroup>>();
const iframe = ref<HTMLIFrameElement>();
const previewVisible = ref(false); const previewVisible = ref(false);
const value = ref(dsl); const value = ref(dsl);
const defaultSelected = ref(dsl.items[0].id); const defaultSelected = ref(dsl.items[0].id);
@ -107,6 +116,14 @@ const menu: MenuBarData = {
} }
} }
previewVisible.value = true; previewVisible.value = true;
await nextTick();
if (!iframe.value?.contentWindow || !deviceGroup.value?.viewerDevice) return;
Object.defineProperty(iframe.value.contentWindow.navigator, 'userAgent', {
value: uaMap[deviceGroup.value.viewerDevice],
writable: true,
});
}, },
}, },
{ {

15
pnpm-lock.yaml generated
View File

@ -665,6 +665,9 @@ importers:
'@element-plus/icons-vue': '@element-plus/icons-vue':
specifier: ^2.0.9 specifier: ^2.0.9
version: 2.0.9(vue@3.2.37) version: 2.0.9(vue@3.2.37)
'@tmagic/core':
specifier: 1.2.13
version: link:../packages/core
'@tmagic/design': '@tmagic/design':
specifier: 1.2.13 specifier: 1.2.13
version: link:../packages/design version: link:../packages/design
@ -843,8 +846,8 @@ importers:
specifier: ^4.0.2 specifier: ^4.0.2
version: 4.0.2(terser@5.14.2)(vite@4.2.1) version: 4.0.2(terser@5.14.2)(vite@4.2.1)
'@vitejs/plugin-vue2': '@vitejs/plugin-vue2':
specifier: ^1.1.2 specifier: ^2.2.0
version: 1.1.2(vite@4.2.1)(vue@2.7.4) version: 2.2.0(vite@4.2.1)(vue@2.7.4)
recast: recast:
specifier: ^0.20.4 specifier: ^0.20.4
version: 0.20.4 version: 0.20.4
@ -3495,11 +3498,11 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@vitejs/plugin-vue2@1.1.2(vite@4.2.1)(vue@2.7.4): /@vitejs/plugin-vue2@2.2.0(vite@4.2.1)(vue@2.7.4):
resolution: {integrity: sha512-y6OEA+2UdJ0xrEQHodq20v9r3SpS62IOHrgN92JPLvVpNkhcissu7yvD5PXMzMESyazj0XNWGsc8UQk8+mVrjQ==} resolution: {integrity: sha512-1km7zEuZ/9QRPvzXSjikbTYGQPG86Mq1baktpC4sXqsXlb02HQKfi+fl8qVS703JM7cgm24Ga9j+RwKmvFn90A==}
engines: {node: '>=14.6.0'} engines: {node: ^14.18.0 || >= 16.0.0}
peerDependencies: peerDependencies:
vite: '>=2.5.10' vite: ^3.0.0 || ^4.0.0
vue: ^2.7.0-0 vue: ^2.7.0-0
dependencies: dependencies:
vite: 4.2.1(@types/node@18.15.11)(sass@1.35.1)(terser@5.14.2) vite: 4.2.1(@types/node@18.15.11)(sass@1.35.1)(terser@5.14.2)

View File

@ -25,7 +25,7 @@
} }
</style> </style>
</head> </head>
<body> <body style="font-size: 14px">
<div id="root"></div> <div id="root"></div>
<script type="module" src="./main.tsx"></script> <script type="module" src="./main.tsx"></script>
</body> </body>

View File

@ -50,14 +50,14 @@ const getLocalConfig = (): MApp[] => {
window.magicDSL = []; window.magicDSL = [];
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({ const app = new Core({
designWidth, ua: window.navigator.userAgent,
config: ((getUrlParam('localPreview') ? getLocalConfig() : window.magicDSL) || [])[0] || {}, config: ((getUrlParam('localPreview') ? getLocalConfig() : window.magicDSL) || [])[0] || {},
curPage: getUrlParam('page'), curPage: getUrlParam('page'),
}); });
app.setDesignWidth(app.env.isWeb ? window.document.documentElement.getBoundingClientRect().width : 375);
Object.keys(components).forEach((type: string) => app.registerComponent(type, components[type])); Object.keys(components).forEach((type: string) => app.registerComponent(type, components[type]));
Object.values(plugins).forEach((plugin: any) => { Object.values(plugins).forEach((plugin: any) => {
plugin.install(app); plugin.install(app);

View File

@ -35,13 +35,15 @@ declare global {
} }
} }
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({ const app = new Core({
designWidth, ua: window.navigator.userAgent,
platform: 'editor', platform: 'editor',
}); });
if (app.env.isWeb) {
app.setDesignWidth(window.document.documentElement.getBoundingClientRect().width);
}
window.appInstance = app; window.appInstance = app;
let curPageId = ''; let curPageId = '';

View File

@ -41,7 +41,7 @@
"sass": "^1.35.1", "sass": "^1.35.1",
"vite": "^4.2.1", "vite": "^4.2.1",
"@vitejs/plugin-legacy": "^4.0.2", "@vitejs/plugin-legacy": "^4.0.2",
"@vitejs/plugin-vue2": "^1.1.2", "@vitejs/plugin-vue2": "^2.2.0",
"vue-template-compiler": "^2.7.4" "vue-template-compiler": "^2.7.4"
} }
} }

View File

@ -25,7 +25,7 @@
</style> </style>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head> </head>
<body> <body style="font-size: 14px">
<div id="app"></div> <div id="app"></div>
<script type="module" src="./main.ts"></script> <script type="module" src="./main.ts"></script>
</body> </body>

View File

@ -30,14 +30,14 @@ import { getLocalConfig } from './utils';
Vue.use(request); Vue.use(request);
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({ const app = new Core({
designWidth, ua: window.navigator.userAgent,
config: ((getUrlParam('localPreview') ? getLocalConfig() : window.magicDSL) || [])[0] || {}, config: ((getUrlParam('localPreview') ? getLocalConfig() : window.magicDSL) || [])[0] || {},
curPage: getUrlParam('page'), curPage: getUrlParam('page'),
}); });
app.setDesignWidth(app.env.isWeb ? window.document.documentElement.getBoundingClientRect().width : 375);
Object.keys(components).forEach((type: string) => { Object.keys(components).forEach((type: string) => {
Vue.component(`magic-ui-${type}`, components[type]); Vue.component(`magic-ui-${type}`, components[type]);
}); });

View File

@ -31,13 +31,17 @@ Promise.all([import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry')]
Vue.use(plugin); Vue.use(plugin);
}); });
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({ const app = new Core({
designWidth, ua: window.navigator.userAgent,
platform: 'editor', platform: 'editor',
}); });
if (app.env.isWeb) {
app.setDesignWidth(window.document.documentElement.getBoundingClientRect().width);
}
window.appInstance = app;
Vue.prototype.app = app; Vue.prototype.app = app;
new Vue({ new Vue({

View File

@ -25,7 +25,7 @@
</style> </style>
<script src="https://unpkg.com/vue@next/dist/vue.runtime.global.js"></script> <script src="https://unpkg.com/vue@next/dist/vue.runtime.global.js"></script>
</head> </head>
<body> <body style="font-size: 14px">
<div id="app"></div> <div id="app"></div>
<script type="module" src="./main.ts"></script> <script type="module" src="./main.ts"></script>
</body> </body>

View File

@ -40,14 +40,14 @@ Object.values(plugins).forEach((plugin: any) => {
magicApp.use(plugin); magicApp.use(plugin);
}); });
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({ const app = new Core({
designWidth, ua: window.navigator.userAgent,
config: ((getUrlParam('localPreview') ? getLocalConfig() : window.magicDSL) || [])[0] || {}, config: ((getUrlParam('localPreview') ? getLocalConfig() : window.magicDSL) || [])[0] || {},
curPage: getUrlParam('page'), curPage: getUrlParam('page'),
}); });
app.setDesignWidth(app.env.isWeb ? window.document.documentElement.getBoundingClientRect().width : 375);
magicApp.config.globalProperties.app = app; magicApp.config.globalProperties.app = app;
magicApp.provide('app', app); magicApp.provide('app', app);

View File

@ -33,12 +33,16 @@ Promise.all([import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry')]
magicApp.use(plugin); magicApp.use(plugin);
}); });
const designWidth = document.documentElement.getBoundingClientRect().width;
const app = new Core({ const app = new Core({
designWidth, ua: window.navigator.userAgent,
platform: 'editor', platform: 'editor',
}); });
if (app.env.isWeb) {
app.setDesignWidth(window.document.documentElement.getBoundingClientRect().width);
}
window.appInstance = app;
magicApp.config.globalProperties.app = app; magicApp.config.globalProperties.app = app;
magicApp.provide('app', app); magicApp.provide('app', app);