mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-04-06 03:57:56 +08:00
feat(core): 完善屏幕大小自动适配
This commit is contained in:
parent
9f8088164e
commit
59f05270ae
@ -39,9 +39,10 @@ import { DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX } from '@tmagic/utils';
|
|||||||
|
|
||||||
import Env from './Env';
|
import Env from './Env';
|
||||||
import { bindCommonEventListener, isCommonMethod, triggerCommonMethod } from './events';
|
import { bindCommonEventListener, isCommonMethod, triggerCommonMethod } from './events';
|
||||||
|
import Flexible from './Flexible';
|
||||||
import Node from './Node';
|
import Node from './Node';
|
||||||
import Page from './Page';
|
import Page from './Page';
|
||||||
import { calcFontsize, transformStyle as defaultTransformStyle } from './utils';
|
import { transformStyle as defaultTransformStyle } from './utils';
|
||||||
|
|
||||||
interface AppOptionsConfig {
|
interface AppOptionsConfig {
|
||||||
ua?: string;
|
ua?: string;
|
||||||
@ -73,7 +74,6 @@ class App extends EventEmitter implements AppCore {
|
|||||||
public useMock = false;
|
public useMock = false;
|
||||||
public platform = 'mobile';
|
public platform = 'mobile';
|
||||||
public jsEngine: JsEngine = 'browser';
|
public jsEngine: JsEngine = 'browser';
|
||||||
public designWidth = 375;
|
|
||||||
public request?: RequestFunction;
|
public request?: RequestFunction;
|
||||||
|
|
||||||
public components = new Map();
|
public components = new Map();
|
||||||
@ -81,6 +81,8 @@ class App extends EventEmitter implements AppCore {
|
|||||||
public eventQueueMap: Record<string, EventCache[]> = {};
|
public eventQueueMap: Record<string, EventCache[]> = {};
|
||||||
public transformStyle: (style: Record<string, any>) => Record<string, any>;
|
public transformStyle: (style: Record<string, any>) => Record<string, any>;
|
||||||
|
|
||||||
|
public flexible?: Flexible;
|
||||||
|
|
||||||
private eventList = new Map<(fromCpt: Node, ...args: any[]) => void, string>();
|
private eventList = new Map<(fromCpt: Node, ...args: any[]) => void, string>();
|
||||||
private dataSourceEventList = new Map<string, Map<string, (...args: any[]) => void>>();
|
private dataSourceEventList = new Map<string, Map<string, (...args: any[]) => void>>();
|
||||||
|
|
||||||
@ -97,8 +99,8 @@ class App extends EventEmitter implements AppCore {
|
|||||||
this.useMock = options.useMock;
|
this.useMock = options.useMock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof options.designWidth !== 'undefined') {
|
if (this.jsEngine === 'browser') {
|
||||||
this.setDesignWidth(options.designWidth);
|
this.flexible = new Flexible({ designWidth: options.designWidth });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.transformStyle =
|
this.transformStyle =
|
||||||
@ -120,13 +122,7 @@ class App extends EventEmitter implements AppCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setDesignWidth(width: number) {
|
public setDesignWidth(width: number) {
|
||||||
this.designWidth = width;
|
this.flexible?.setDesignWidth(width);
|
||||||
// 根据屏幕大小计算出跟节点的font-size,用于rem样式的适配
|
|
||||||
if (this.jsEngine === 'browser') {
|
|
||||||
this.calcFontsize();
|
|
||||||
globalThis.removeEventListener('resize', this.calcFontsize);
|
|
||||||
globalThis.addEventListener('resize', this.calcFontsize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -331,9 +327,8 @@ class App extends EventEmitter implements AppCore {
|
|||||||
this.removeAllListeners();
|
this.removeAllListeners();
|
||||||
this.page = undefined;
|
this.page = undefined;
|
||||||
|
|
||||||
if (this.jsEngine === 'browser') {
|
this.flexible?.destroy();
|
||||||
globalThis.removeEventListener('resize', this.calcFontsize);
|
this.flexible = undefined;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bindDataSourceEvents() {
|
private bindDataSourceEvents() {
|
||||||
@ -418,10 +413,6 @@ class App extends EventEmitter implements AppCore {
|
|||||||
this.eventQueueMap[event.eventConfig.to] = [event];
|
this.eventQueueMap[event.eventConfig.to] = [event];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private calcFontsize() {
|
|
||||||
calcFontsize(this.designWidth);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
@ -27,6 +27,7 @@ class Env {
|
|||||||
isMqq = false;
|
isMqq = false;
|
||||||
isWechat = false;
|
isWechat = false;
|
||||||
isWeb = false;
|
isWeb = false;
|
||||||
|
isOpenHarmony = false;
|
||||||
|
|
||||||
constructor(ua = globalThis.navigator.userAgent, options: Record<string, boolean | string> = {}) {
|
constructor(ua = globalThis.navigator.userAgent, options: Record<string, boolean | string> = {}) {
|
||||||
this.isIphone = ua.indexOf('iPhone') >= 0;
|
this.isIphone = ua.indexOf('iPhone') >= 0;
|
||||||
@ -47,7 +48,9 @@ class Env {
|
|||||||
|
|
||||||
this.isWechat = ua.indexOf('MicroMessenger') >= 0 && ua.indexOf('wxwork') < 0;
|
this.isWechat = ua.indexOf('MicroMessenger') >= 0 && ua.indexOf('wxwork') < 0;
|
||||||
|
|
||||||
this.isWeb = !this.isIos && !this.isAndroid && !/(WebOS|BlackBerry)/.test(ua);
|
this.isOpenHarmony = ua.includes('OpenHarmony');
|
||||||
|
|
||||||
|
this.isWeb = !this.isIos && !this.isAndroid && !this.isOpenHarmony && !/(WebOS|BlackBerry)/.test(ua);
|
||||||
|
|
||||||
Object.entries(options).forEach(([key, value]) => {
|
Object.entries(options).forEach(([key, value]) => {
|
||||||
(this as any)[key] = value;
|
(this as any)[key] = value;
|
||||||
|
72
packages/core/src/Flexible.ts
Normal file
72
packages/core/src/Flexible.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
export default class Flexible {
|
||||||
|
public designWidth = 375;
|
||||||
|
private tid: NodeJS.Timeout | undefined;
|
||||||
|
|
||||||
|
constructor(options?: { designWidth?: number }) {
|
||||||
|
if (globalThis.document.readyState === 'complete') {
|
||||||
|
this.setBodyFontSize();
|
||||||
|
} else {
|
||||||
|
globalThis.document.addEventListener('DOMContentLoaded', this.setBodyFontSize, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
globalThis.addEventListener('resize', this.resizeHandler, false);
|
||||||
|
globalThis.addEventListener('pageshow', this.pageshowHandler, false);
|
||||||
|
|
||||||
|
if (typeof options?.designWidth !== 'undefined') {
|
||||||
|
this.setDesignWidth(options.designWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public destroy() {
|
||||||
|
globalThis.document.removeEventListener('DOMContentLoaded', this.setBodyFontSize, false);
|
||||||
|
globalThis.removeEventListener('resize', this.resizeHandler, false);
|
||||||
|
globalThis.removeEventListener('pageshow', this.pageshowHandler, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setDesignWidth(width: number) {
|
||||||
|
this.designWidth = width;
|
||||||
|
this.refreshRem();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setBodyFontSize() {
|
||||||
|
globalThis.document.body.style.fontSize = '.12rem';
|
||||||
|
}
|
||||||
|
|
||||||
|
public refreshRem() {
|
||||||
|
const { width } = document.documentElement.getBoundingClientRect();
|
||||||
|
const fontSize = width / (this.designWidth / 100);
|
||||||
|
globalThis.document.documentElement.style.fontSize = `${fontSize}px`;
|
||||||
|
globalThis.document.documentElement.style.fontSize = `${this.correctRem(fontSize)}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 纠正由于文字缩放导致的字体大小计算不正确问题
|
||||||
|
* @param {number} fontSize
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
public correctRem(fontSize: number) {
|
||||||
|
const { document } = globalThis;
|
||||||
|
const d = document.createElement('div');
|
||||||
|
d.style.cssText = 'width:1rem;height:0;overflow:hidden;position:absolute;z-index:-1;visibility:hidden;';
|
||||||
|
document.documentElement.appendChild(d);
|
||||||
|
const dw = d.offsetWidth;
|
||||||
|
document.documentElement.removeChild(d);
|
||||||
|
if (Math.abs(dw - fontSize) > 1) {
|
||||||
|
return fontSize ** 2 / dw;
|
||||||
|
}
|
||||||
|
return fontSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private resizeHandler = () => {
|
||||||
|
clearTimeout(this.tid);
|
||||||
|
this.tid = setTimeout(() => {
|
||||||
|
this.refreshRem();
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
private pageshowHandler = (e: PageTransitionEvent) => {
|
||||||
|
if (e.persisted) {
|
||||||
|
this.resizeHandler();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -115,9 +115,3 @@ export const transformStyle = (style: Record<string, any> | string, jsEngine: Js
|
|||||||
|
|
||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const calcFontsize = (designWidth: number) => {
|
|
||||||
const { width } = document.documentElement.getBoundingClientRect();
|
|
||||||
const fontSize = width / (designWidth / 100);
|
|
||||||
document.documentElement.style.fontSize = `${fontSize}px`;
|
|
||||||
};
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user