one-screen-scale 1.0.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -7,7 +7,6 @@ export interface ScaleOptions {
7
7
  targetHeight?: number
8
8
  mode?: 'contain' | 'fixed-width'
9
9
  visualWidth?: number
10
- screenWidth?: number
11
10
  }
12
11
 
13
12
  export interface ScalerOptions {
@@ -15,6 +14,17 @@ export interface ScalerOptions {
15
14
  visualWidth?: number
16
15
  origin?: string
17
16
  autoResize?: boolean
17
+ /**
18
+ * 是否自动注入模式所需基础样式(默认 true)
19
+ * - contain: width:100vw; min-height:100vh/100dvh
20
+ * - fixed-width: 暂不注入(宽高由 refresh 行内补偿)
21
+ */
22
+ injectBaseStyles?: boolean
23
+ /**
24
+ * 内容尺寸变化时自动重算(默认 true)。
25
+ * 监听 ResizeObserver / 内部图片 load 等,避免图未加载完就测量导致 scale 偏大。
26
+ */
27
+ observeContent?: boolean
18
28
  }
19
29
 
20
30
  export interface ScalerInstance {
@@ -24,17 +34,83 @@ export interface ScalerInstance {
24
34
  getScale: () => number
25
35
  }
26
36
 
37
+ export const BASE_CLASS: {
38
+ contain: string
39
+ 'fixed-width': string
40
+ compensate: string
41
+ }
42
+
43
+ export const SCALE_CHANGE_EVENT: 'one-screen-scale-change'
44
+ export const CANVAS_RESIZE_EVENT: 'one-screen-scale-canvas-resize'
45
+
27
46
  export function calculateScale(options: ScaleOptions): number
28
47
  export function applyScale(el: HTMLElement | string, scale: number, origin?: string): void
29
48
  export function getPageScale(el?: HTMLElement | string): number
30
49
  export function getInverseScale(el?: HTMLElement | string): number
31
50
  export function createScaler(el: HTMLElement | string, options?: ScalerOptions): ScalerInstance
51
+ export function ensureBaseStyleSheet(): HTMLStyleElement | null
52
+ export function applyBaseStyles(el: HTMLElement, mode?: 'contain' | 'fixed-width'): string | null
53
+ export function removeBaseStyles(el: HTMLElement): void
54
+ export function applyCompensateStyles(el: HTMLElement): string | null
55
+ export function removeCompensateStyles(el: HTMLElement): void
56
+
57
+ // ===== 组件反缩放补偿(仅抵消页面 v-fit-screen 的 scale;不处理浏览器 Ctrl+/-) =====
58
+
59
+ export interface CompensateRefreshDetail {
60
+ scale: number
61
+ inverseScale: number
62
+ el: HTMLElement
63
+ }
64
+
65
+ export interface CompensateOptions {
66
+ /**
67
+ * 补偿后通知子树 canvas 重绘:探测 ECharts / Chart.js,
68
+ * 并对每个 <canvas> 派发 CANVAS_RESIZE_EVENT。
69
+ */
70
+ resizeCanvas?: boolean
71
+ /** @deprecated 请用 resizeCanvas;传入 echarts 模块时仍表示开启 + 注入库 */
72
+ echarts?: boolean | { getInstanceByDom?: (el: Element) => { resize: (opts?: object) => void } | undefined }
73
+ echartsLib?: { getInstanceByDom?: (el: Element) => { resize: (opts?: object) => void } | undefined }
74
+ onRefresh?: (detail: CompensateRefreshDetail) => void
75
+ }
76
+
77
+ export interface CompensateInstance {
78
+ refresh: () => void
79
+ stop: () => void
80
+ }
81
+
82
+ export function resolvePageScale(fromEl?: HTMLElement | null): number
83
+ export function applyCompensateTransform(el: HTMLElement): {
84
+ scale: number
85
+ inverseScale: number
86
+ }
87
+ export function clearCompensateTransform(el: HTMLElement): void
88
+ export function resizeCanvasUnder(el: HTMLElement, echartsLib?: CompensateOptions['echartsLib']): number
89
+ /** @deprecated 请用 resizeCanvasUnder */
90
+ export function resizeEchartsUnder(el: HTMLElement, echartsLib?: CompensateOptions['echartsLib']): number
91
+ export function createCompensate(
92
+ el: HTMLElement,
93
+ options?: CompensateOptions | (() => CompensateOptions)
94
+ ): CompensateInstance
95
+ /** 全局注入 echarts,供 resizeCanvas 探测(无需每个调用传模块) */
96
+ export function setCompensateEcharts(echarts: CompensateOptions['echartsLib'] | null): void
32
97
 
33
98
  // ===== Vue =====
34
99
 
35
100
  import type { Ref, Directive } from 'vue'
36
101
 
37
- export const vFitScreen: Directive<HTMLElement, ScalerOptions>
102
+ export const vFitScreen: Directive<HTMLElement, ScalerOptions | undefined>
103
+ /**
104
+ * 第三方组件反缩放。修饰符 `.resize-canvas` 或 `{ resizeCanvas: true }` 通知子树 canvas 重绘。
105
+ */
106
+ export const vCompensate: Directive<
107
+ HTMLElement,
108
+ CompensateOptions | 'resize-canvas' | 'resizeCanvas' | 'echarts' | undefined
109
+ >
110
+ export const vFitCompensate: Directive<
111
+ HTMLElement,
112
+ CompensateOptions | 'resize-canvas' | 'resizeCanvas' | 'echarts' | undefined
113
+ >
38
114
 
39
115
  export function useFitScreen(
40
116
  targetRef: Ref<HTMLElement | null> | HTMLElement,
package/dist/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import{ref as e,onMounted as t,watch as n,onUnmounted as r}from"vue";function i(e){return e?"string"==typeof e?document.querySelector(e):e instanceof HTMLElement?e:e.value instanceof HTMLElement?e.value:e.current instanceof HTMLElement?e.current:null:null}function o({sourceWidth:e,sourceHeight:t,targetWidth:n=("undefined"!=typeof window?window.innerWidth:1920),targetHeight:r=("undefined"!=typeof window?window.innerHeight:1080),mode:i="contain",visualWidth:o=450,screenWidth:s=("undefined"!=typeof window?window.screen.width:1920)}){if(!e||!t||e<=0||t<=0)return 1;let u;if("fixed-width"===i)u=s<o?1:o/Math.max(n,s);else{const i=n/e,o=r/t;u=Math.min(i,o)}return u}function s(e,t,n="top center"){const r=i(e);r&&(r.style.transform=`scale(${t})`,r.style.transformOrigin=n)}function u(e){const t=i(e);if(!t)return 1;const n=window.getComputedStyle(t).transform;if(!n||"none"===n)return 1;const r=n.match(/matrix\(([^,]+),\s*[^,]+,\s*[^,]+,\s*([^,]+)/);if(r)return(parseFloat(r[1])+parseFloat(r[2]))/2;const o=n.match(/matrix3d\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\)/);if(o)return(parseFloat(o[1])+parseFloat(o[2]))/2;const s=n.match(/scale\(([^)]+)\)/);if(s){const e=s[1].split(",").map(e=>parseFloat(e.trim()));return e.length>=2?(e[0]+e[1])/2:e[0]}return 1}function a(e=".share-page"){const t=u(e);return t>0?1/t:1}function c(e,t={}){const n=i(e);if(!n)throw new Error("[one-screen-scale] element not found");const{mode:r="contain",visualWidth:u=450,origin:a="top center",autoResize:c=!0}=t;let l=1,d=null;function f(){const e=o({sourceWidth:n.offsetWidth,sourceHeight:n.offsetHeight,targetWidth:window.innerWidth,targetHeight:window.innerHeight,mode:r,visualWidth:u,screenWidth:window.screen.width});return e!==l&&(l=e,s(n,e,a),"fixed-width"===r&&e>0&&(n.style.width=`${Math.max(window.innerWidth,window.screen.width)}px`,n.style.height=`${Math.round(window.innerHeight/e)}px`)),l}return{start:function(){return f(),c&&(d=()=>f(),window.addEventListener("resize",d)),l},stop:function(){d&&(window.removeEventListener("resize",d),d=null)},refresh:f,getScale:()=>l}}const l={mounted(e,t){const n=c(e,t.value||{});n.start(),e.__fitScreenScaler=n},updated(e,t){const n=e.__fitScreenScaler;n&&(t.value,n.refresh())},unmounted(e){const t=e.__fitScreenScaler;t&&(t.stop(),delete e.__fitScreenScaler)}};function d(i,o={}){const s=e(1),u=e(1);let l=null,d=null;function f(e){if(!e)return;l=c(e,o);const t=l.start();s.value=t,u.value=a(e),d=()=>{s.value=l?.getScale?.()??1,u.value=a(e)},window.addEventListener("resize",d)}t(()=>{f(i?.value??i)}),i&&"object"==typeof i&&"value"in i&&n(()=>i.value,e=>{e&&!l&&f(e)}),r(()=>{d&&(window.removeEventListener("resize",d),d=null),l?.stop(),l=null});return{scale:s,inverseScale:u,refresh:()=>{const e=i?.value??i;if(!e||!l)return;const t=l.refresh();s.value=t,u.value=a(e)}}}export{s as applyScale,o as calculateScale,c as createScaler,a as getInverseScale,u as getPageScale,d as useFitScreen,l as vFitScreen};
1
+ import{ref as e,onMounted as t,watch as n,onUnmounted as r}from"vue";const o="one-screen-scale-base-styles",i={contain:"one-screen-scale--contain","fixed-width":"one-screen-scale--fixed-width",compensate:"one-screen-scale--compensate"},s=`\n.${i.contain} {\n width: 100vw;\n min-height: 100vh;\n min-height: 100dvh;\n}\n/* fixed-width:占位 class,样式先不注入 */\n.${i["fixed-width"]} {\n}\n/*\n * 纯 CSS 反缩放(可选)。v-compensate 指令已改为 JS 行内写入同一公式,更稳。\n * ECharts/Canvas:请用 offsetWidth 量布局盒,勿用 getBoundingClientRect。\n */\n.${i.compensate} {\n transform: scale(var(--one-screen-inverse-scale, 1));\n transform-origin: top left;\n width: calc(100% * var(--one-screen-scale, 1));\n height: calc(100% * var(--one-screen-scale, 1));\n}\n`.trim();function a(){if("undefined"==typeof document)return null;let e=document.getElementById(o);return e?(e.textContent=s,e):(e=document.createElement("style"),e.id=o,e.textContent=s,document.head.appendChild(e),e)}function c(e,t="contain"){if(!e||void 0===e.classList)return null;a();const n=i[t]||i.contain;return[i.contain,i["fixed-width"]].forEach(t=>{t!==n&&e.classList.remove(t)}),e.classList.add(n),n}function l(e){e&&void 0!==e.classList&&e.classList.remove(i.contain,i["fixed-width"])}function u(e){return e&&void 0!==e.classList?(a(),e.classList.add(i.compensate),i.compensate):null}function f(e){e&&void 0!==e.classList&&e.classList.remove(i.compensate)}function d(e){return e?"string"==typeof e?document.querySelector(e):e instanceof HTMLElement?e:e.value instanceof HTMLElement?e.value:e.current instanceof HTMLElement?e.current:null:null}function h({sourceWidth:e,sourceHeight:t,targetWidth:n=("undefined"!=typeof window?window.innerWidth:1920),targetHeight:r=("undefined"!=typeof window?window.innerHeight:1080),mode:o="contain",visualWidth:i=450}){if(!e||!t||e<=0||t<=0)return 1;let s;if("fixed-width"===o)s=n>i?i/n:1;else{const o=n/e,i=r/t;s=Math.min(o,i)}return s}const m="one-screen-scale-change";function p(e,t,n="top center"){const r=d(e);if(!r)return;r.style.transform=`scale(${t})`,r.style.transformOrigin=n;const o=t>0?1/t:1;r.style.setProperty("--one-screen-scale",String(t)),r.style.setProperty("--one-screen-inverse-scale",String(o)),"undefined"!=typeof window&&window.dispatchEvent(new CustomEvent(m,{detail:{scale:t,inverseScale:o,el:r}}))}function v(e){const t=d(e);if(!t)return 1;const n=window.getComputedStyle(t).transform;if(!n||"none"===n)return 1;const r=n.match(/matrix\(([^,]+),\s*[^,]+,\s*[^,]+,\s*([^,]+)/);if(r)return(parseFloat(r[1])+parseFloat(r[2]))/2;const o=n.match(/matrix3d\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\)/);if(o)return(parseFloat(o[1])+parseFloat(o[2]))/2;const i=n.match(/scale\(([^)]+)\)/);if(i){const e=i[1].split(",").map(e=>parseFloat(e.trim()));return e.length>=2?(e[0]+e[1])/2:e[0]}return 1}function y(e=".share-page"){const t=v(e);return t>0?1/t:1}function w(e,t={}){const n=d(e);if(!n)throw new Error("[one-screen-scale] element not found");const{mode:r="contain",visualWidth:o=450,origin:i="top center",autoResize:s=!0,injectBaseStyles:a=!0,observeContent:u=!0}=t;let f=1,m=null,v=null,y=null,w=0,g=0,S=null,_=!1,C={w:0,h:0},E=0;const b={width:n.style.width,height:n.style.height,transform:n.style.transform,transformOrigin:n.style.transformOrigin};function L(){_=!0;const e=function(){const e=n.offsetWidth,t=n.offsetHeight,i=document.documentElement.clientWidth||window.innerWidth,s=window.innerHeight;return C={w:e,h:t},h({sourceWidth:e,sourceHeight:t,targetWidth:i,targetHeight:s,mode:r,visualWidth:o})}();if(f=e,p(n,e,i),"fixed-width"===r&&e>0){const t=`${document.documentElement.clientWidth||window.innerWidth}px`,r=`${Math.round(window.innerHeight/e)}px`;n.style.width!==t&&(n.style.width=t),n.style.height!==r&&(n.style.height=r)}const t=E;return cancelAnimationFrame(g),g=requestAnimationFrame(()=>{t===E&&(_=!1)}),f}function z(){if(_)return;cancelAnimationFrame(w);const e=E;w=requestAnimationFrame(()=>{if(e!==E)return;const t=n.offsetWidth,r=n.offsetHeight;t===C.w&&r===C.h&&n.style.transform||L()})}function O(){L()}return{start:function(){E+=1;const e=E;return _=!1,a&&c(n,r),L(),s&&(m=O,window.addEventListener("resize",m)),u&&"undefined"!=typeof window&&("undefined"!=typeof ResizeObserver&&(S=new ResizeObserver(()=>z()),S.observe(n)),v=e=>{const t=e.target;!t||"IMG"!==t.tagName&&"VIDEO"!==t.tagName&&"IFRAME"!==t.tagName||z()},n.addEventListener("load",v,!0),n.addEventListener("error",v,!0),document.fonts&&document.fonts.ready&&document.fonts.ready.then(()=>{e===E&&z()}).catch(()=>{}),"complete"===document.readyState?z():(y=()=>z(),window.addEventListener("load",y,{once:!0})),requestAnimationFrame(()=>{requestAnimationFrame(()=>z())})),f},stop:function(){E+=1,m&&(window.removeEventListener("resize",m),m=null),v&&(n.removeEventListener("load",v,!0),n.removeEventListener("error",v,!0),v=null),y&&(window.removeEventListener("load",y),y=null),S&&(S.disconnect(),S=null),cancelAnimationFrame(w),cancelAnimationFrame(g),w=0,g=0,a&&l(n),n.style.width=b.width,n.style.height=b.height,n.style.transform=b.transform,n.style.transformOrigin=b.transformOrigin,n.style.removeProperty("--one-screen-scale"),n.style.removeProperty("--one-screen-inverse-scale")},refresh:L,getScale:()=>f}}const g="one-screen-scale-canvas-resize";let S=null;function _(e){S=e||null}function C(e){if(!e||"undefined"==typeof getComputedStyle)return NaN;const t=getComputedStyle(e).getPropertyValue("--one-screen-scale").trim();if(!t)return NaN;const n=parseFloat(t);return n>0?n:NaN}function E(e){if(!e||"undefined"==typeof getComputedStyle)return NaN;const t=getComputedStyle(e).transform;if(!t||"none"===t)return NaN;const n=t.match(/matrix\(([^,]+),\s*[^,]+,\s*[^,]+,\s*([^,]+)/);if(n)return(parseFloat(n[1])+parseFloat(n[2]))/2;const r=t.match(/matrix3d\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\)/);if(r)return(parseFloat(r[1])+parseFloat(r[2]))/2;const o=t.match(/scale\(([^)]+)\)/);if(o){const e=o[1].split(",").map(e=>parseFloat(e.trim()));return e.length>=2?(e[0]+e[1])/2:e[0]}return NaN}function b(e){let t=e;for(;t&&1===t.nodeType;){const e=C(t);if(e>0)return e;t=t.parentElement}for(t=e;t&&1===t.nodeType;){if(!t.__oneScreenCompensate){const e=E(t);if(e>0&&1!==e)return e}t=t.parentElement}return 1}function L(e){if(!e)return{scale:1,inverseScale:1};const t=b(e),n=t>0?1/t:1;return e.style.transform=`scale(${n})`,e.style.transformOrigin="top left",e.style.width=100*t+"%",e.style.height=100*t+"%",e.style.overflow="visible",e.__oneScreenCompensate=!0,{scale:t,inverseScale:n}}function z(e){e&&(e.style.transform="",e.style.transformOrigin="",e.style.width="",e.style.height="",e.style.overflow="",delete e.__oneScreenCompensate)}function O(e){return{width:Math.max(1,Math.round(e?.offsetWidth||0)),height:Math.max(1,Math.round(e?.offsetHeight||0))}}function F(e,t){if(!e||"function"!=typeof t)return!1;let n;try{n=t(e)}catch{return!1}if(!n||"function"!=typeof n.resize)return!1;const{width:r,height:o}=O(e);try{return n.resize({width:r,height:o}),!0}catch{return!1}}function A(e){const t="undefined"!=typeof globalThis?globalThis.Chart:null,n=t?.getChart;if("function"!=typeof n)return!1;let r;try{r=n(e)}catch{return!1}if(!r||"function"!=typeof r.resize)return!1;try{return r.resize(),!0}catch{return!1}}function W(e,t){if(!e)return 0;const n=t||S||("undefined"!=typeof globalThis?globalThis.echarts:null)||null;const r=n?.getInstanceByDom;let o=0;const i=e.querySelectorAll?e.querySelectorAll("canvas"):[];for(const t of i){const n=t.parentElement||t,{width:i,height:s}=O(n);(F(t,r)||F(n,r))&&(o+=1),A(t)&&(o+=1);try{t.dispatchEvent(new CustomEvent(g,{bubbles:!0,detail:{width:i,height:s,canvas:t,el:e}}))}catch{}}if("function"==typeof r){const t=[e,...e.querySelectorAll("div")];for(const e of t)F(e,r)&&(o+=1)}return o}function x(e,t){return W(e,t)}function N(e={}){return Boolean(e.resizeCanvas||e.echarts||e.echartsLib)}function R(e={}){return"object"==typeof e.echarts?e.echarts:e.echartsLib?e.echartsLib:void 0}function H(e){const t="function"==typeof e?e():e;return t&&"object"==typeof t?t:{}}function M(e,t={}){if(!e)throw new Error("[one-screen-scale] compensate element required");const n=N(H(t));let r=0,o=null,i=null,s=[],a=!1;const c=()=>{s.forEach(e=>clearTimeout(e)),s=[]},l=()=>{if(a)return;const n=H(t),{scale:r,inverseScale:o}=L(e);if("function"==typeof n.onRefresh)try{n.onRefresh({scale:r,inverseScale:o,el:e})}catch{}if(N(n)){const r=R(n);0===W(e,r)&&(c(),[50,200].forEach(n=>{const r=setTimeout(()=>{if(a)return;const n=H(t);W(e,R(n))},n);s.push(r)}))}},u=()=>{a||(cancelAnimationFrame(r),r=requestAnimationFrame(()=>{r=0,a||l()}))};l(),"undefined"!=typeof window&&(window.addEventListener(m,u),window.addEventListener("resize",u)),"undefined"!=typeof ResizeObserver&&(o=new ResizeObserver(u),e.parentElement&&o.observe(e.parentElement),o.observe(e)),n&&"undefined"!=typeof MutationObserver&&(i=new MutationObserver(u),i.observe(e,{childList:!0,subtree:!0}));return{refresh:l,stop:()=>{a=!0,cancelAnimationFrame(r),c(),r=0,"undefined"!=typeof window&&(window.removeEventListener(m,u),window.removeEventListener("resize",u)),o?.disconnect(),o=null,i?.disconnect(),i=null,z(e)}}}function j(e){return e.value&&"object"==typeof e.value?e.value:{}}function B(e,t){const n=j(t),r=w(e,n);r.start(),e.__fitScreenScaler=r,e.__fitScreenOptionsKey=JSON.stringify({mode:n.mode||"contain",visualWidth:n.visualWidth,origin:n.origin,autoResize:n.autoResize,injectBaseStyles:n.injectBaseStyles,observeContent:n.observeContent})}function T(e){const t=e.__fitScreenScaler;t&&(t.stop(),delete e.__fitScreenScaler,delete e.__fitScreenOptionsKey)}const q={mounted(e,t){B(e,t)},updated(e,t){const n=j(t),r=JSON.stringify({mode:n.mode||"contain",visualWidth:n.visualWidth,origin:n.origin,autoResize:n.autoResize,injectBaseStyles:n.injectBaseStyles,observeContent:n.observeContent});if(e.__fitScreenOptionsKey!==r)return T(e),void B(e,t);e.__fitScreenScaler?.refresh()},unmounted(e){T(e)}};function $(e){const t=e?.value,n=e?.modifiers||{},r=t&&"object"==typeof t?{...t}:{};return(n.resizeCanvas||n["resize-canvas"]||n.echarts||"resize-canvas"===t||"resizeCanvas"===t||"echarts"===t)&&(r.resizeCanvas=r.resizeCanvas||!0),r}function K(e){return JSON.stringify({resizeCanvas:Boolean(e.resizeCanvas||e.echarts||e.echartsLib),hasLib:Boolean(e.echarts&&"object"==typeof e.echarts||e.echartsLib),hasOnRefresh:"function"==typeof e.onRefresh})}function I(e){const t=M(e,()=>e.__oneScreenCompensateOptions||{});e.__oneScreenCompensateApi=t,e.__oneScreenCompensateKey=K(e.__oneScreenCompensateOptions||{})}const P={mounted(e,t){e.__oneScreenCompensateOptions=$(t),I(e)},updated(e,t){const n=$(t),r=K(n);if(e.__oneScreenCompensateOptions=n,e.__oneScreenCompensateKey!==r)return e.__oneScreenCompensateApi?.stop(),void I(e);e.__oneScreenCompensateApi?.refresh()},unmounted(e){e.__oneScreenCompensateApi?.stop(),delete e.__oneScreenCompensateApi,delete e.__oneScreenCompensateKey,delete e.__oneScreenCompensateOptions}},J=P;function D(o,i={}){const s=e(1),a=e(1);let c=null,l=null;function u(e){if(!e)return;c=w(e,i);const t=c.start();s.value=t,a.value=t>0?1/t:1,l=t=>{t.detail?.el===e&&(s.value=t.detail.scale,a.value=t.detail.inverseScale)},window.addEventListener(m,l)}t(()=>{u(o?.value??o)}),o&&"object"==typeof o&&"value"in o&&n(()=>o.value,e=>{e&&!c&&u(e)}),r(()=>{l&&(window.removeEventListener(m,l),l=null),c?.stop(),c=null});return{scale:s,inverseScale:a,refresh:()=>{if(!(o?.value??o)||!c)return;const e=c.refresh();s.value=e,a.value=e>0?1/e:1}}}export{i as BASE_CLASS,g as CANVAS_RESIZE_EVENT,m as SCALE_CHANGE_EVENT,c as applyBaseStyles,u as applyCompensateStyles,L as applyCompensateTransform,p as applyScale,h as calculateScale,z as clearCompensateTransform,M as createCompensate,w as createScaler,a as ensureBaseStyleSheet,y as getInverseScale,v as getPageScale,l as removeBaseStyles,f as removeCompensateStyles,W as resizeCanvasUnder,x as resizeEchartsUnder,b as resolvePageScale,_ as setCompensateEcharts,D as useFitScreen,P as vCompensate,J as vFitCompensate,q as vFitScreen};
2
2
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/core.js","../src/directives.js","../src/composables.js"],"sourcesContent":["/**\n * 一屏自适应缩放 — 核心算法(框架无关)\n *\n * 两种模式:\n * 'contain' 一屏展示,内容不溢出,用 min(scaleX, scaleY)\n * 'fixed-width' 固定视觉宽度,内容可滚动,反向补高\n */\n\n// ---------- helpers ----------\n\nfunction resolveEl(el) {\n if (!el) return null\n if (typeof el === 'string') return document.querySelector(el)\n if (el instanceof HTMLElement) return el\n // Vue ref / React ref\n if (el.value instanceof HTMLElement) return el.value\n if (el.current instanceof HTMLElement) return el.current\n return null\n}\n\n// ---------- scale calculation ----------\n\nexport function calculateScale({\n sourceWidth,\n sourceHeight,\n targetWidth = (typeof window !== 'undefined' ? window.innerWidth : 1920),\n targetHeight = (typeof window !== 'undefined' ? window.innerHeight : 1080),\n mode = 'contain',\n visualWidth = 450, // fixed-width 模式下的目标视觉宽度\n screenWidth = (typeof window !== 'undefined' ? window.screen.width : 1920), // fixed-width 模式下的设备屏幕宽度\n}) {\n if (!sourceWidth || !sourceHeight || sourceWidth <= 0 || sourceHeight <= 0) return 1\n\n let scale\n\n if (mode === 'fixed-width') {\n if(screenWidth < visualWidth){\n scale = 1\n }else{\n scale = visualWidth / Math.max(targetWidth, screenWidth)\n }\n } else {\n const sx = targetWidth / sourceWidth\n const sy = targetHeight / sourceHeight\n scale = Math.min(sx, sy)\n }\n\n return scale\n}\n\n// ---------- apply / read ----------\n\nexport function applyScale(el, scale, origin = 'top center') {\n const target = resolveEl(el)\n if (!target) return\n target.style.transform = `scale(${scale})`\n target.style.transformOrigin = origin\n}\n\nexport function getPageScale(el) {\n const target = resolveEl(el)\n if (!target) return 1\n\n const style = window.getComputedStyle(target)\n const t = style.transform\n if (!t || t === 'none') return 1\n\n // matrix(a, b, c, d, e, f) — 2d\n const m2 = t.match(/matrix\\(([^,]+),\\s*[^,]+,\\s*[^,]+,\\s*([^,]+)/)\n if (m2) return (parseFloat(m2[1]) + parseFloat(m2[2])) / 2\n\n // matrix3d — 3d\n const m3 = t.match(/matrix3d\\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\\)/)\n if (m3) return (parseFloat(m3[1]) + parseFloat(m3[2])) / 2\n\n // scale(x, y) or scale(s)\n const sm = t.match(/scale\\(([^)]+)\\)/)\n if (sm) {\n const vals = sm[1].split(',').map(v => parseFloat(v.trim()))\n return vals.length >= 2 ? (vals[0] + vals[1]) / 2 : vals[0]\n }\n\n return 1\n}\n\nexport function getInverseScale(el = '.share-page') {\n const s = getPageScale(el)\n return s > 0 ? 1 / s : 1\n}\n\n// ---------- scaler instance ----------\n\nexport function createScaler(el, options = {}) {\n const target = resolveEl(el)\n if (!target) throw new Error('[one-screen-scale] element not found')\n\n const {\n mode = 'contain',\n visualWidth = 450,\n origin = 'top center',\n autoResize = true\n } = options\n\n let currentScale = 1\n let handler = null\n\n function compute() {\n const sw = target.offsetWidth\n const sh = target.offsetHeight\n const tw = window.innerWidth\n const th = window.innerHeight\n\n return calculateScale({\n sourceWidth: sw,\n sourceHeight: sh,\n targetWidth: tw,\n targetHeight: th,\n mode,\n visualWidth,\n screenWidth: window.screen.width\n })\n }\n\n function refresh() {\n const next = compute()\n if (next !== currentScale) {\n currentScale = next\n applyScale(target, next, origin)\n\n // fixed-width 模式:反向补偿高度\n if (mode === 'fixed-width' && next > 0) {\n target.style.width = `${Math.max(window.innerWidth, window.screen.width)}px`\n target.style.height = `${Math.round(window.innerHeight / next)}px`\n }\n }\n return currentScale\n }\n\n function start() {\n refresh()\n if (autoResize) {\n handler = () => refresh()\n window.addEventListener('resize', handler)\n }\n return currentScale\n }\n\n function stop() {\n if (handler) {\n window.removeEventListener('resize', handler)\n handler = null\n }\n }\n\n return { start, stop, refresh, getScale: () => currentScale }\n}\n","/**\n * Vue 3 指令\n * v-fit-screen 页面级缩放\n * v-compensate 组件级反缩放补偿\n */\nimport { createScaler } from './core.js'\n\n// ---- v-fit-screen ----\n\nexport const vFitScreen = {\n mounted(el, binding) {\n const options = binding.value || {}\n const scaler = createScaler(el, options)\n scaler.start()\n el.__fitScreenScaler = scaler\n },\n\n updated(el, binding) {\n const scaler = el.__fitScreenScaler\n if (scaler) {\n const options = binding.value || {}\n // 简单处理:重新 refresh\n scaler.refresh()\n }\n },\n\n unmounted(el) {\n const scaler = el.__fitScreenScaler\n if (scaler) {\n scaler.stop()\n delete el.__fitScreenScaler\n }\n }\n}\n","/**\n * Vue 3 Composable\n * useFitScreen(ref, options) → { scale, inverseScale, refresh }\n */\nimport { ref, onMounted, onUnmounted, watch } from 'vue'\nimport { createScaler, getInverseScale } from './core.js'\n\nexport function useFitScreen(targetRef, options = {}) {\n const scale = ref(1)\n const inverseScale = ref(1)\n\n let scaler = null\n let onResize = null\n\n function setup(el) {\n if (!el) return\n scaler = createScaler(el, options)\n const s = scaler.start()\n scale.value = s\n inverseScale.value = getInverseScale(el)\n\n onResize = () => {\n scale.value = scaler?.getScale?.() ?? 1\n inverseScale.value = getInverseScale(el)\n }\n window.addEventListener('resize', onResize)\n }\n\n function teardown() {\n if (onResize) {\n window.removeEventListener('resize', onResize)\n onResize = null\n }\n scaler?.stop()\n scaler = null\n }\n\n // 处理 ref 初始有值的情况\n onMounted(() => {\n const el = targetRef?.value ?? targetRef\n setup(el)\n })\n\n // 处理 ref 延迟赋值的情况(异步挂载)\n if (targetRef && typeof targetRef === 'object' && 'value' in targetRef) {\n watch(\n () => targetRef.value,\n (el) => {\n if (el && !scaler) setup(el)\n }\n )\n }\n\n onUnmounted(() => {\n teardown()\n })\n\n const refresh = () => {\n const el = targetRef?.value ?? targetRef\n if (!el || !scaler) return\n const s = scaler.refresh()\n scale.value = s\n inverseScale.value = getInverseScale(el)\n }\n\n return { scale, inverseScale, refresh }\n}\n"],"names":["resolveEl","el","document","querySelector","HTMLElement","value","current","calculateScale","sourceWidth","sourceHeight","targetWidth","window","innerWidth","targetHeight","innerHeight","mode","visualWidth","screenWidth","screen","width","scale","Math","max","sx","sy","min","applyScale","origin","target","style","transform","transformOrigin","getPageScale","t","getComputedStyle","m2","match","parseFloat","m3","sm","vals","split","map","v","trim","length","getInverseScale","s","createScaler","options","Error","autoResize","currentScale","handler","refresh","next","offsetWidth","offsetHeight","height","round","start","addEventListener","stop","removeEventListener","getScale","vFitScreen","mounted","binding","scaler","__fitScreenScaler","updated","unmounted","useFitScreen","targetRef","ref","inverseScale","onResize","setup","onMounted","watch","onUnmounted"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/baseStyles.js","../src/core.js","../src/compensate.js","../src/directives.js","../src/composables.js"],"sourcesContent":["/**\n * 指令挂载时注入的「适配生效」基础样式。\n *\n * 前提:页面用了 postcss-px-to-viewport(或同类)把设计稿 px 转成 vw。\n *\n * - contain:宽拉满视口 + 最小一屏高,高度由内容撑开\n * - fixed-width:宽高由 refresh 行内补偿,暂不注入\n * - compensate:第三方组件反缩放(抵消页面 scale,ECharts / Element Plus 等)\n */\n\nexport const STYLE_ELEMENT_ID = 'one-screen-scale-base-styles'\n\nexport const BASE_CLASS = {\n contain: 'one-screen-scale--contain',\n 'fixed-width': 'one-screen-scale--fixed-width',\n compensate: 'one-screen-scale--compensate',\n}\n\nconst BASE_CSS = `\n.${BASE_CLASS.contain} {\n width: 100vw;\n min-height: 100vh;\n min-height: 100dvh;\n}\n/* fixed-width:占位 class,样式先不注入 */\n.${BASE_CLASS['fixed-width']} {\n}\n/*\n * 纯 CSS 反缩放(可选)。v-compensate 指令已改为 JS 行内写入同一公式,更稳。\n * ECharts/Canvas:请用 offsetWidth 量布局盒,勿用 getBoundingClientRect。\n */\n.${BASE_CLASS.compensate} {\n transform: scale(var(--one-screen-inverse-scale, 1));\n transform-origin: top left;\n width: calc(100% * var(--one-screen-scale, 1));\n height: calc(100% * var(--one-screen-scale, 1));\n}\n`.trim()\n\n/** 向 document 注入 / 同步基础样式表(已存在则更新内容,便于本地迭代) */\nexport function ensureBaseStyleSheet() {\n if (typeof document === 'undefined') return null\n let styleEl = document.getElementById(STYLE_ELEMENT_ID)\n if (styleEl) {\n styleEl.textContent = BASE_CSS\n return styleEl\n }\n\n styleEl = document.createElement('style')\n styleEl.id = STYLE_ELEMENT_ID\n styleEl.textContent = BASE_CSS\n document.head.appendChild(styleEl)\n return styleEl\n}\n\n/**\n * 给缩放根节点挂上对应模式的 class。\n * @returns {string | null} 本次加上的 class,便于 stop 时移除\n */\nexport function applyBaseStyles(el, mode = 'contain') {\n if (!el || typeof el.classList === 'undefined') return null\n ensureBaseStyleSheet()\n\n const nextClass = BASE_CLASS[mode] || BASE_CLASS.contain\n // 切换模式时清掉另一套页面级 class(不动 compensate)\n ;[BASE_CLASS.contain, BASE_CLASS['fixed-width']].forEach((cls) => {\n if (cls !== nextClass) el.classList.remove(cls)\n })\n el.classList.add(nextClass)\n return nextClass\n}\n\n/** 移除本库注入的页面级基础 class(不含 compensate) */\nexport function removeBaseStyles(el) {\n if (!el || typeof el.classList === 'undefined') return\n el.classList.remove(BASE_CLASS.contain, BASE_CLASS['fixed-width'])\n}\n\n/** 挂上反缩放补偿 class */\nexport function applyCompensateStyles(el) {\n if (!el || typeof el.classList === 'undefined') return null\n ensureBaseStyleSheet()\n el.classList.add(BASE_CLASS.compensate)\n return BASE_CLASS.compensate\n}\n\n/** 移除反缩放补偿 class */\nexport function removeCompensateStyles(el) {\n if (!el || typeof el.classList === 'undefined') return\n el.classList.remove(BASE_CLASS.compensate)\n}\n","/**\n * 一屏自适应缩放 — 核心算法(框架无关)\n *\n * 两种模式:\n * 'contain' 一屏展示,内容不溢出,用 min(scaleX, scaleY)\n * 'fixed-width' 固定视觉宽度,内容可滚动,反向补高\n *\n * 配套前提:H5 使用 postcss-px-to-viewport(或同类)做移动端适配。\n * createScaler / 指令默认会注入基础宽高样式,保证测量与缩放生效。\n *\n * 图片等异步内容会改变 offsetHeight:默认用 ResizeObserver / 图片 load\n * 在尺寸稳定后再 refresh,避免首屏偶发「量矮了 → scale 偏大」。\n */\n\nimport { applyBaseStyles, removeBaseStyles } from './baseStyles.js'\n\n// ---------- helpers ----------\n\nfunction resolveEl(el) {\n if (!el) return null\n if (typeof el === 'string') return document.querySelector(el)\n if (el instanceof HTMLElement) return el\n // Vue ref / React ref\n if (el.value instanceof HTMLElement) return el.value\n if (el.current instanceof HTMLElement) return el.current\n return null\n}\n\n// ---------- scale calculation ----------\n\nexport function calculateScale({\n sourceWidth,\n sourceHeight,\n targetWidth = (typeof window !== 'undefined' ? window.innerWidth : 1920),\n targetHeight = (typeof window !== 'undefined' ? window.innerHeight : 1080),\n mode = 'contain',\n visualWidth = 450, // fixed-width 模式下的目标视觉宽度\n}) {\n if (!sourceWidth || !sourceHeight || sourceWidth <= 0 || sourceHeight <= 0) return 1\n\n let scale\n\n if (mode === 'fixed-width') {\n // 只用视口宽:视口比目标宽才缩小,否则 1:1(保持清晰)\n scale = targetWidth > visualWidth ? visualWidth / targetWidth : 1\n } else {\n const sx = targetWidth / sourceWidth\n const sy = targetHeight / sourceHeight\n scale = Math.min(sx, sy)\n }\n\n return scale\n}\n\n// ---------- apply / read ----------\n\n/** 页面 scale 变化时抛出,供 ECharts.resize / 业务监听 */\nexport const SCALE_CHANGE_EVENT = 'one-screen-scale-change'\n\nexport function applyScale(el, scale, origin = 'top center') {\n const target = resolveEl(el)\n if (!target) return\n target.style.transform = `scale(${scale})`\n target.style.transformOrigin = origin\n // 供业务 / v-compensate 做反缩放(继承到子树)\n const inv = scale > 0 ? 1 / scale : 1\n target.style.setProperty('--one-screen-scale', String(scale))\n target.style.setProperty('--one-screen-inverse-scale', String(inv))\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(SCALE_CHANGE_EVENT, { detail: { scale, inverseScale: inv, el: target } })\n )\n }\n}\n\nexport function getPageScale(el) {\n const target = resolveEl(el)\n if (!target) return 1\n\n const style = window.getComputedStyle(target)\n const t = style.transform\n if (!t || t === 'none') return 1\n\n // matrix(a, b, c, d, e, f) — 2d\n const m2 = t.match(/matrix\\(([^,]+),\\s*[^,]+,\\s*[^,]+,\\s*([^,]+)/)\n if (m2) return (parseFloat(m2[1]) + parseFloat(m2[2])) / 2\n\n // matrix3d — 3d\n const m3 = t.match(/matrix3d\\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\\)/)\n if (m3) return (parseFloat(m3[1]) + parseFloat(m3[2])) / 2\n\n // scale(x, y) or scale(s)\n const sm = t.match(/scale\\(([^)]+)\\)/)\n if (sm) {\n const vals = sm[1].split(',').map(v => parseFloat(v.trim()))\n return vals.length >= 2 ? (vals[0] + vals[1]) / 2 : vals[0]\n }\n\n return 1\n}\n\nexport function getInverseScale(el = '.share-page') {\n const s = getPageScale(el)\n return s > 0 ? 1 / s : 1\n}\n\n// ---------- scaler instance ----------\n\nexport function createScaler(el, options = {}) {\n const target = resolveEl(el)\n if (!target) throw new Error('[one-screen-scale] element not found')\n\n const {\n mode = 'contain',\n visualWidth = 450,\n origin = 'top center',\n autoResize = true,\n /** 是否自动注入模式所需的宽高基础样式,默认 true */\n injectBaseStyles = true,\n /**\n * 内容尺寸变化时自动重算(图片 load、字体、DOM 撑高)。\n * 解决刷新偶发「图未加载完就测量 → scale 偏大」。\n */\n observeContent = true,\n } = options\n\n let currentScale = 1\n let resizeHandler = null\n let loadHandler = null\n let windowLoadHandler = null\n let rafId = 0\n let unlockRaf = 0\n let ro = null\n let refreshing = false\n let lastMeasured = { w: 0, h: 0 }\n // start / stop 各加一,用来丢掉停掉之后才回来的字体、帧回调\n let session = 0\n\n // fixed-width 会改 inline width/height,stop 时还原\n const savedInline = {\n width: target.style.width,\n height: target.style.height,\n transform: target.style.transform,\n transformOrigin: target.style.transformOrigin,\n }\n\n function compute() {\n const sw = target.offsetWidth\n const sh = target.offsetHeight\n const tw = document.documentElement.clientWidth || window.innerWidth\n const th = window.innerHeight\n\n lastMeasured = { w: sw, h: sh }\n\n return calculateScale({\n sourceWidth: sw,\n sourceHeight: sh,\n targetWidth: tw,\n targetHeight: th,\n mode,\n visualWidth,\n })\n }\n\n function refresh() {\n refreshing = true\n const next = compute()\n currentScale = next\n // 始终写入,保证首次 scale=1 时也带上 transform-origin\n applyScale(target, next, origin)\n\n // fixed-width 模式:反向补偿高度(视觉宽固定,布局宽仍用视口宽再缩小)\n if (mode === 'fixed-width' && next > 0) {\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth\n const nextW = `${viewportWidth}px`\n const nextH = `${Math.round(window.innerHeight / next)}px`\n // 值不变不写,避免 ResizeObserver 死循环\n if (target.style.width !== nextW) target.style.width = nextW\n if (target.style.height !== nextH) target.style.height = nextH\n }\n // 等布局提交后再放开,避免 RO 回调里立刻重入\n const token = session\n cancelAnimationFrame(unlockRaf)\n unlockRaf = requestAnimationFrame(() => {\n if (token !== session) return\n refreshing = false\n })\n return currentScale\n }\n\n function scheduleRefresh() {\n if (refreshing) return\n cancelAnimationFrame(rafId)\n const token = session\n rafId = requestAnimationFrame(() => {\n if (token !== session) return\n // 尺寸没变就跳过(fixed-width 改 height 触发的 RO)\n const w = target.offsetWidth\n const h = target.offsetHeight\n if (w === lastMeasured.w && h === lastMeasured.h && target.style.transform) {\n // 视口变化仍需算:由 window.resize 路径直接 refresh\n return\n }\n refresh()\n })\n }\n\n function onWindowResize() {\n refresh()\n }\n\n function start() {\n session += 1\n const token = session\n // 复用同一实例 start 时,上一次 stop 之后留下的锁要清掉\n refreshing = false\n if (injectBaseStyles) {\n applyBaseStyles(target, mode)\n }\n // 注入样式后再量尺寸\n refresh()\n\n if (autoResize) {\n resizeHandler = onWindowResize\n window.addEventListener('resize', resizeHandler)\n }\n\n if (observeContent && typeof window !== 'undefined') {\n // 1) 子树布局尺寸变化(图片解码后撑高最常见)\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => scheduleRefresh())\n ro.observe(target)\n }\n\n // 2) 捕获阶段听内部 img/video 的 load(含后插入的节点)\n loadHandler = (e) => {\n const t = e.target\n if (t && (t.tagName === 'IMG' || t.tagName === 'VIDEO' || t.tagName === 'IFRAME')) {\n scheduleRefresh()\n }\n }\n target.addEventListener('load', loadHandler, true)\n target.addEventListener('error', loadHandler, true)\n\n // 3) 字体就绪。stop 之后 session 变了,这次回调直接丢掉\n if (document.fonts && document.fonts.ready) {\n document.fonts.ready\n .then(() => {\n if (token !== session) return\n scheduleRefresh()\n })\n .catch(() => {})\n }\n\n // 4) 整页资源 load(缓存命中时可能已 complete)\n if (document.readyState === 'complete') {\n scheduleRefresh()\n } else {\n windowLoadHandler = () => scheduleRefresh()\n window.addEventListener('load', windowLoadHandler, { once: true })\n }\n\n // 5) 再等两帧,覆盖首屏同步布局抖动\n requestAnimationFrame(() => {\n requestAnimationFrame(() => scheduleRefresh())\n })\n }\n\n return currentScale\n }\n\n function stop() {\n session += 1\n if (resizeHandler) {\n window.removeEventListener('resize', resizeHandler)\n resizeHandler = null\n }\n if (loadHandler) {\n target.removeEventListener('load', loadHandler, true)\n target.removeEventListener('error', loadHandler, true)\n loadHandler = null\n }\n if (windowLoadHandler) {\n window.removeEventListener('load', windowLoadHandler)\n windowLoadHandler = null\n }\n if (ro) {\n ro.disconnect()\n ro = null\n }\n cancelAnimationFrame(rafId)\n cancelAnimationFrame(unlockRaf)\n rafId = 0\n unlockRaf = 0\n\n if (injectBaseStyles) {\n removeBaseStyles(target)\n }\n target.style.width = savedInline.width\n target.style.height = savedInline.height\n target.style.transform = savedInline.transform\n target.style.transformOrigin = savedInline.transformOrigin\n target.style.removeProperty('--one-screen-scale')\n target.style.removeProperty('--one-screen-inverse-scale')\n }\n\n return { start, stop, refresh, getScale: () => currentScale }\n}\n\nexport {\n applyBaseStyles,\n removeBaseStyles,\n applyCompensateStyles,\n removeCompensateStyles,\n ensureBaseStyleSheet,\n BASE_CLASS,\n} from './baseStyles.js'\n","/**\n * 组件级反缩放补偿(与业务 WinRateChart 手写公式一致):\n * transform: scale(inverse); width/height: 100% * pageScale; origin: top left\n *\n * 只抵消页面 v-fit-screen 的 scale;不处理浏览器 Ctrl+/-。\n */\n\nimport { SCALE_CHANGE_EVENT } from './core.js'\n\n/** 子树 canvas 需要重绘时抛出(挂在每个 <canvas> 上) */\nexport const CANVAS_RESIZE_EVENT = 'one-screen-scale-canvas-resize'\n\n/** @type {null | { getInstanceByDom?: (el: Element) => { resize: Function } | undefined }} */\nlet registeredEcharts = null\n\n/** 业务可注入 echarts 模块(避免插件硬依赖);供 resizeCanvas 探测 */\nexport function setCompensateEcharts(echarts) {\n registeredEcharts = echarts || null\n}\n\nfunction readCssVarScale(el) {\n if (!el || typeof getComputedStyle === 'undefined') return NaN\n const raw = getComputedStyle(el).getPropertyValue('--one-screen-scale').trim()\n if (!raw) return NaN\n const v = parseFloat(raw)\n return v > 0 ? v : NaN\n}\n\nfunction readTransformScale(el) {\n if (!el || typeof getComputedStyle === 'undefined') return NaN\n const t = getComputedStyle(el).transform\n if (!t || t === 'none') return NaN\n\n const m2 = t.match(/matrix\\(([^,]+),\\s*[^,]+,\\s*[^,]+,\\s*([^,]+)/)\n if (m2) return (parseFloat(m2[1]) + parseFloat(m2[2])) / 2\n\n const m3 = t.match(\n /matrix3d\\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\\)/\n )\n if (m3) return (parseFloat(m3[1]) + parseFloat(m3[2])) / 2\n\n const sm = t.match(/scale\\(([^)]+)\\)/)\n if (sm) {\n const vals = sm[1].split(',').map((v) => parseFloat(v.trim()))\n return vals.length >= 2 ? (vals[0] + vals[1]) / 2 : vals[0]\n }\n return NaN\n}\n\n/** 从 fromEl 向上解析页面 scale(跳过已挂补偿的节点自身 transform) */\nexport function resolvePageScale(fromEl) {\n let node = fromEl\n while (node && node.nodeType === 1) {\n const fromVar = readCssVarScale(node)\n if (fromVar > 0) return fromVar\n node = node.parentElement\n }\n\n node = fromEl\n while (node && node.nodeType === 1) {\n if (!node.__oneScreenCompensate) {\n const fromTf = readTransformScale(node)\n if (fromTf > 0 && fromTf !== 1) return fromTf\n }\n node = node.parentElement\n }\n return 1\n}\n\n/**\n * 给槽位内层写入反缩放行内样式。父槽位需有明确宽高。\n * @returns {{ scale: number, inverseScale: number }}\n */\nexport function applyCompensateTransform(el) {\n if (!el) return { scale: 1, inverseScale: 1 }\n const scale = resolvePageScale(el)\n const inverseScale = scale > 0 ? 1 / scale : 1\n el.style.transform = `scale(${inverseScale})`\n el.style.transformOrigin = 'top left'\n el.style.width = `${100 * scale}%`\n el.style.height = `${100 * scale}%`\n el.style.overflow = 'visible'\n el.__oneScreenCompensate = true\n return { scale, inverseScale }\n}\n\nexport function clearCompensateTransform(el) {\n if (!el) return\n el.style.transform = ''\n el.style.transformOrigin = ''\n el.style.width = ''\n el.style.height = ''\n el.style.overflow = ''\n delete el.__oneScreenCompensate\n}\n\nfunction resolveEchartsLib(bindingEcharts) {\n return (\n bindingEcharts ||\n registeredEcharts ||\n (typeof globalThis !== 'undefined' ? globalThis.echarts : null) ||\n null\n )\n}\n\nfunction boxSize(node) {\n const w = Math.max(1, Math.round(node?.offsetWidth || 0))\n const h = Math.max(1, Math.round(node?.offsetHeight || 0))\n return { width: w, height: h }\n}\n\nfunction tryEchartsResize(node, getInst) {\n if (!node || typeof getInst !== 'function') return false\n let inst\n try {\n inst = getInst(node)\n } catch {\n return false\n }\n if (!inst || typeof inst.resize !== 'function') return false\n const { width, height } = boxSize(node)\n try {\n inst.resize({ width, height })\n return true\n } catch {\n return false\n }\n}\n\nfunction tryChartJsResize(canvas) {\n const Chart = typeof globalThis !== 'undefined' ? globalThis.Chart : null\n const getChart = Chart?.getChart\n if (typeof getChart !== 'function') return false\n let chart\n try {\n chart = getChart(canvas)\n } catch {\n return false\n }\n if (!chart || typeof chart.resize !== 'function') return false\n try {\n chart.resize()\n return true\n } catch {\n return false\n }\n}\n\n/**\n * 补偿后通知子树 canvas 重绘:\n * - 探测 ECharts / Chart.js(若已加载)\n * - 每个 <canvas> 派发 CANVAS_RESIZE_EVENT,业务可自行监听重绘\n * 量尺寸用 offsetWidth(勿用 getBoundingClientRect)\n *\n * @returns {number} 成功调用已知图表库 resize 的次数\n */\nexport function resizeCanvasUnder(el, echartsLib) {\n if (!el) return 0\n\n const echarts = resolveEchartsLib(echartsLib)\n const getInst = echarts?.getInstanceByDom\n let count = 0\n\n const canvases = el.querySelectorAll ? el.querySelectorAll('canvas') : []\n for (const canvas of canvases) {\n const host = canvas.parentElement || canvas\n const { width, height } = boxSize(host)\n\n if (tryEchartsResize(canvas, getInst)) count += 1\n else if (tryEchartsResize(host, getInst)) count += 1\n\n if (tryChartJsResize(canvas)) count += 1\n\n try {\n canvas.dispatchEvent(\n new CustomEvent(CANVAS_RESIZE_EVENT, {\n bubbles: true,\n detail: { width, height, canvas, el },\n })\n )\n } catch {\n /* ignore */\n }\n }\n\n // ECharts 常挂在 div 上(不一定已有 canvas)\n if (typeof getInst === 'function') {\n const nodes = [el, ...el.querySelectorAll('div')]\n for (const node of nodes) {\n if (tryEchartsResize(node, getInst)) count += 1\n }\n }\n\n return count\n}\n\n/** @deprecated 请用 resizeCanvasUnder */\nexport function resizeEchartsUnder(el, echartsLib) {\n return resizeCanvasUnder(el, echartsLib)\n}\n\nfunction wantsResizeCanvas(options = {}) {\n return Boolean(\n options.resizeCanvas ||\n options.echarts || // 兼容旧名\n options.echartsLib\n )\n}\n\nfunction resolveBoundEcharts(options = {}) {\n if (typeof options.echarts === 'object') return options.echarts\n if (options.echartsLib) return options.echartsLib\n return undefined\n}\n\n/** options 可以是对象,也可以是返回最新对象的函数(指令 / hook 传 getter 用) */\nfunction readLiveOptions(options) {\n const value = typeof options === 'function' ? options() : options\n return value && typeof value === 'object' ? value : {}\n}\n\n/**\n * @param {HTMLElement} el\n * @param {{\n * resizeCanvas?: boolean,\n * echarts?: boolean | object,\n * echartsLib?: object,\n * onRefresh?: Function\n * } | (() => object)} [options]\n */\nexport function createCompensate(el, options = {}) {\n if (!el) throw new Error('[one-screen-scale] compensate element required')\n\n const initial = readLiveOptions(options)\n const wantResize = wantsResizeCanvas(initial)\n let raf = 0\n let ro = null\n let mo = null\n let retryTimers = []\n let stopped = false\n\n const clearRetries = () => {\n retryTimers.forEach((id) => clearTimeout(id))\n retryTimers = []\n }\n\n const refresh = () => {\n if (stopped) return\n const live = readLiveOptions(options)\n const { scale, inverseScale } = applyCompensateTransform(el)\n if (typeof live.onRefresh === 'function') {\n try {\n live.onRefresh({ scale, inverseScale, el })\n } catch {\n /* user callback */\n }\n }\n if (wantsResizeCanvas(live)) {\n const lib = resolveBoundEcharts(live)\n const n = resizeCanvasUnder(el, lib)\n if (n === 0) {\n clearRetries()\n ;[50, 200].forEach((delay) => {\n const id = setTimeout(() => {\n if (stopped) return\n const next = readLiveOptions(options)\n resizeCanvasUnder(el, resolveBoundEcharts(next))\n }, delay)\n retryTimers.push(id)\n })\n }\n }\n }\n\n const schedule = () => {\n if (stopped) return\n cancelAnimationFrame(raf)\n raf = requestAnimationFrame(() => {\n raf = 0\n if (stopped) return\n refresh()\n })\n }\n\n refresh()\n\n if (typeof window !== 'undefined') {\n window.addEventListener(SCALE_CHANGE_EVENT, schedule)\n window.addEventListener('resize', schedule)\n }\n\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(schedule)\n if (el.parentElement) ro.observe(el.parentElement)\n ro.observe(el)\n }\n\n if (wantResize && typeof MutationObserver !== 'undefined') {\n mo = new MutationObserver(schedule)\n mo.observe(el, { childList: true, subtree: true })\n }\n\n const stop = () => {\n stopped = true\n cancelAnimationFrame(raf)\n clearRetries()\n raf = 0\n if (typeof window !== 'undefined') {\n window.removeEventListener(SCALE_CHANGE_EVENT, schedule)\n window.removeEventListener('resize', schedule)\n }\n ro?.disconnect()\n ro = null\n mo?.disconnect()\n mo = null\n clearCompensateTransform(el)\n }\n\n return { refresh, stop }\n}\n","/**\n * Vue 3 指令\n * v-fit-screen 页面级缩放\n * v-compensate 组件级反缩放补偿(ECharts / Element Plus 等)\n */\nimport { createScaler } from './core.js'\nimport { createCompensate } from './compensate.js'\n\nfunction readOptions(binding) {\n return binding.value && typeof binding.value === 'object' ? binding.value : {}\n}\n\nfunction mountScaler(el, binding) {\n const options = readOptions(binding)\n const scaler = createScaler(el, options)\n scaler.start()\n el.__fitScreenScaler = scaler\n el.__fitScreenOptionsKey = JSON.stringify({\n mode: options.mode || 'contain',\n visualWidth: options.visualWidth,\n origin: options.origin,\n autoResize: options.autoResize,\n injectBaseStyles: options.injectBaseStyles,\n observeContent: options.observeContent,\n })\n}\n\nfunction unmountScaler(el) {\n const scaler = el.__fitScreenScaler\n if (scaler) {\n scaler.stop()\n delete el.__fitScreenScaler\n delete el.__fitScreenOptionsKey\n }\n}\n\n// ---- v-fit-screen ----\n\nexport const vFitScreen = {\n mounted(el, binding) {\n mountScaler(el, binding)\n },\n\n updated(el, binding) {\n const options = readOptions(binding)\n const key = JSON.stringify({\n mode: options.mode || 'contain',\n visualWidth: options.visualWidth,\n origin: options.origin,\n autoResize: options.autoResize,\n injectBaseStyles: options.injectBaseStyles,\n observeContent: options.observeContent,\n })\n\n if (el.__fitScreenOptionsKey !== key) {\n unmountScaler(el)\n mountScaler(el, binding)\n return\n }\n\n el.__fitScreenScaler?.refresh()\n },\n\n unmounted(el) {\n unmountScaler(el)\n },\n}\n\nfunction readCompensateOptions(binding) {\n const value = binding?.value\n const modifiers = binding?.modifiers || {}\n const options = value && typeof value === 'object' ? { ...value } : {}\n // v-compensate.resize-canvas / .resizeCanvas / 旧名 .echarts\n if (\n modifiers.resizeCanvas ||\n modifiers['resize-canvas'] ||\n modifiers.echarts ||\n value === 'resize-canvas' ||\n value === 'resizeCanvas' ||\n value === 'echarts'\n ) {\n options.resizeCanvas = options.resizeCanvas || true\n }\n return options\n}\n\nfunction compensateOptionsKey(options) {\n return JSON.stringify({\n resizeCanvas: Boolean(options.resizeCanvas || options.echarts || options.echartsLib),\n hasLib: Boolean(\n (options.echarts && typeof options.echarts === 'object') || options.echartsLib\n ),\n hasOnRefresh: typeof options.onRefresh === 'function',\n })\n}\n\n/**\n * v-compensate — 挂在「被页面 scale 搞坏」的第三方组件外包一层。\n *\n * 原理与业务 WinRateChart 手写一致(JS 行内,非纯 CSS):\n * transform: scale(inverse); width/height: 100% * pageScale; origin: top left\n *\n * 用法:\n * <div class=\"slot\"><div v-compensate><Whatever /></div></div>\n * <div class=\"slot\"><div v-compensate.resize-canvas><Chart /></div></div>\n *\n * `.resize-canvas` / `{ resizeCanvas: true }`:补偿后通知子树 canvas 重绘\n * (探测 ECharts / Chart.js,并派发 one-screen-scale-canvas-resize)。\n */\nfunction mountCompensate(el) {\n const api = createCompensate(el, () => el.__oneScreenCompensateOptions || {})\n el.__oneScreenCompensateApi = api\n el.__oneScreenCompensateKey = compensateOptionsKey(el.__oneScreenCompensateOptions || {})\n}\n\nexport const vCompensate = {\n mounted(el, binding) {\n el.__oneScreenCompensateOptions = readCompensateOptions(binding)\n mountCompensate(el)\n },\n\n updated(el, binding) {\n const options = readCompensateOptions(binding)\n const key = compensateOptionsKey(options)\n el.__oneScreenCompensateOptions = options\n // resizeCanvas / 图表库变了才重建监听;onRefresh 每次 refresh 现读\n if (el.__oneScreenCompensateKey !== key) {\n el.__oneScreenCompensateApi?.stop()\n mountCompensate(el)\n return\n }\n el.__oneScreenCompensateApi?.refresh()\n },\n\n unmounted(el) {\n el.__oneScreenCompensateApi?.stop()\n delete el.__oneScreenCompensateApi\n delete el.__oneScreenCompensateKey\n delete el.__oneScreenCompensateOptions\n },\n}\n\n/** 别名,与早期注释里的命名一致 */\nexport const vFitCompensate = vCompensate\n","/**\r\n * Vue 3 Composable\r\n * useFitScreen(ref, options) → { scale, inverseScale, refresh }\r\n */\r\nimport { ref, onMounted, onUnmounted, watch } from 'vue'\r\nimport { createScaler, SCALE_CHANGE_EVENT } from './core.js'\r\n\r\nexport function useFitScreen(targetRef, options = {}) {\r\n const scale = ref(1)\r\n const inverseScale = ref(1)\r\n\r\n let scaler = null\r\n let onScale = null\r\n\r\n function setup(el) {\r\n if (!el) return\r\n scaler = createScaler(el, options)\r\n const s = scaler.start()\r\n scale.value = s\r\n inverseScale.value = s > 0 ? 1 / s : 1\r\n\r\n // 图片加载等导致的重算不经过 window.resize,跟页面缩放事件走\r\n onScale = (event) => {\r\n if (event.detail?.el !== el) return\r\n scale.value = event.detail.scale\r\n inverseScale.value = event.detail.inverseScale\r\n }\r\n window.addEventListener(SCALE_CHANGE_EVENT, onScale)\r\n }\r\n\r\n function teardown() {\r\n if (onScale) {\r\n window.removeEventListener(SCALE_CHANGE_EVENT, onScale)\r\n onScale = null\r\n }\r\n scaler?.stop()\r\n scaler = null\r\n }\r\n\r\n // 处理 ref 初始有值的情况\r\n onMounted(() => {\r\n const el = targetRef?.value ?? targetRef\r\n setup(el)\r\n })\r\n\r\n // 处理 ref 延迟赋值的情况(异步挂载)\r\n if (targetRef && typeof targetRef === 'object' && 'value' in targetRef) {\r\n watch(\r\n () => targetRef.value,\r\n (el) => {\r\n if (el && !scaler) setup(el)\r\n }\r\n )\r\n }\r\n\r\n onUnmounted(() => {\r\n teardown()\r\n })\r\n\r\n const refresh = () => {\r\n const el = targetRef?.value ?? targetRef\r\n if (!el || !scaler) return\r\n const s = scaler.refresh()\r\n scale.value = s\r\n inverseScale.value = s > 0 ? 1 / s : 1\r\n }\r\n\r\n return { scale, inverseScale, refresh }\r\n}\r\n"],"names":["STYLE_ELEMENT_ID","BASE_CLASS","contain","compensate","BASE_CSS","trim","ensureBaseStyleSheet","document","styleEl","getElementById","textContent","createElement","id","head","appendChild","applyBaseStyles","el","mode","classList","nextClass","forEach","cls","remove","add","removeBaseStyles","applyCompensateStyles","removeCompensateStyles","resolveEl","querySelector","HTMLElement","value","current","calculateScale","sourceWidth","sourceHeight","targetWidth","window","innerWidth","targetHeight","innerHeight","visualWidth","scale","sx","sy","Math","min","SCALE_CHANGE_EVENT","applyScale","origin","target","style","transform","transformOrigin","inv","setProperty","String","dispatchEvent","CustomEvent","detail","inverseScale","getPageScale","t","getComputedStyle","m2","match","parseFloat","m3","sm","vals","split","map","v","length","getInverseScale","s","createScaler","options","Error","autoResize","injectBaseStyles","observeContent","currentScale","resizeHandler","loadHandler","windowLoadHandler","rafId","unlockRaf","ro","refreshing","lastMeasured","w","h","session","savedInline","width","height","refresh","next","sw","offsetWidth","sh","offsetHeight","tw","documentElement","clientWidth","th","compute","nextW","nextH","round","token","cancelAnimationFrame","requestAnimationFrame","scheduleRefresh","onWindowResize","start","addEventListener","ResizeObserver","observe","e","tagName","fonts","ready","then","catch","readyState","once","stop","removeEventListener","disconnect","removeProperty","getScale","CANVAS_RESIZE_EVENT","registeredEcharts","setCompensateEcharts","echarts","readCssVarScale","NaN","raw","getPropertyValue","readTransformScale","resolvePageScale","fromEl","node","nodeType","fromVar","parentElement","__oneScreenCompensate","fromTf","applyCompensateTransform","overflow","clearCompensateTransform","boxSize","max","tryEchartsResize","getInst","inst","resize","tryChartJsResize","canvas","Chart","globalThis","getChart","chart","resizeCanvasUnder","echartsLib","getInstanceByDom","count","canvases","querySelectorAll","host","bubbles","nodes","resizeEchartsUnder","wantsResizeCanvas","Boolean","resizeCanvas","resolveBoundEcharts","readLiveOptions","createCompensate","wantResize","raf","mo","retryTimers","stopped","clearRetries","clearTimeout","live","onRefresh","lib","delay","setTimeout","push","schedule","MutationObserver","childList","subtree","readOptions","binding","mountScaler","scaler","__fitScreenScaler","__fitScreenOptionsKey","JSON","stringify","unmountScaler","vFitScreen","mounted","updated","key","unmounted","readCompensateOptions","modifiers","compensateOptionsKey","hasLib","hasOnRefresh","mountCompensate","api","__oneScreenCompensateOptions","__oneScreenCompensateApi","__oneScreenCompensateKey","vCompensate","vFitCompensate","useFitScreen","targetRef","ref","onScale","setup","event","onMounted","watch","onUnmounted"],"mappings":"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"}
package/dist/react.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react");function t(e){return e?"string"==typeof e?document.querySelector(e):e instanceof HTMLElement?e:e.value instanceof HTMLElement?e.value:e.current instanceof HTMLElement?e.current:null:null}function n(e,n={}){const r=t(e);if(!r)throw new Error("[one-screen-scale] element not found");const{mode:i="contain",visualWidth:o=450,origin:s="top center",autoResize:c=!0}=n;let u=1,d=null;function w(){return function({sourceWidth:e,sourceHeight:t,targetWidth:n=("undefined"!=typeof window?window.innerWidth:1920),targetHeight:r=("undefined"!=typeof window?window.innerHeight:1080),mode:i="contain",visualWidth:o=450,screenWidth:s=("undefined"!=typeof window?window.screen.width:1920)}){if(!e||!t||e<=0||t<=0)return 1;let c;if("fixed-width"===i)c=s<o?1:o/Math.max(n,s);else{const i=n/e,o=r/t;c=Math.min(i,o)}return c}({sourceWidth:r.offsetWidth,sourceHeight:r.offsetHeight,targetWidth:window.innerWidth,targetHeight:window.innerHeight,mode:i,visualWidth:o,screenWidth:window.screen.width})}function a(){const e=w();return e!==u&&(u=e,function(e,n,r="top center"){const i=t(e);i&&(i.style.transform=`scale(${n})`,i.style.transformOrigin=r)}(r,e,s),"fixed-width"===i&&e>0&&(r.style.width=`${Math.max(window.innerWidth,window.screen.width)}px`,r.style.height=`${Math.round(window.innerHeight/e)}px`)),u}return{start:function(){return a(),c&&(d=()=>a(),window.addEventListener("resize",d)),u},stop:function(){d&&(window.removeEventListener("resize",d),d=null)},refresh:a,getScale:()=>u}}exports.useFitScreen=function(t,r={}){const[i,o]=e.useState(1),[s,c]=e.useState(1),u=e.useRef(null);return e.useEffect(()=>{const e=t?.current??t;if(!e)return;const i=n(e,r);u.current=i;const s=i.start();o(s),c(s>0?1/s:1);const d=()=>{const e=i.getScale();o(e),c(e>0?1/e:1)};return window.addEventListener("resize",d),()=>{window.removeEventListener("resize",d),i.stop(),u.current=null}},[t]),{scale:i,inverseScale:s,refresh:e.useCallback(()=>{if(!(t?.current??t)||!u.current)return;const e=u.current.refresh();o(e),c(e>0?1/e:1)},[t])}};
1
+ "use strict";var e=require("react");const t="one-screen-scale-base-styles",n={contain:"one-screen-scale--contain","fixed-width":"one-screen-scale--fixed-width",compensate:"one-screen-scale--compensate"},r=`\n.${n.contain} {\n width: 100vw;\n min-height: 100vh;\n min-height: 100dvh;\n}\n/* fixed-width:占位 class,样式先不注入 */\n.${n["fixed-width"]} {\n}\n/*\n * 纯 CSS 反缩放(可选)。v-compensate 指令已改为 JS 行内写入同一公式,更稳。\n * ECharts/Canvas:请用 offsetWidth 量布局盒,勿用 getBoundingClientRect。\n */\n.${n.compensate} {\n transform: scale(var(--one-screen-inverse-scale, 1));\n transform-origin: top left;\n width: calc(100% * var(--one-screen-scale, 1));\n height: calc(100% * var(--one-screen-scale, 1));\n}\n`.trim();function o(e,o="contain"){if(!e||void 0===e.classList)return null;!function(){if("undefined"==typeof document)return null;let e=document.getElementById(t);e?e.textContent=r:(e=document.createElement("style"),e.id=t,e.textContent=r,document.head.appendChild(e))}();const i=n[o]||n.contain;return[n.contain,n["fixed-width"]].forEach(t=>{t!==i&&e.classList.remove(t)}),e.classList.add(i),i}function i(e){return e?"string"==typeof e?document.querySelector(e):e instanceof HTMLElement?e:e.value instanceof HTMLElement?e.value:e.current instanceof HTMLElement?e.current:null:null}const s="one-screen-scale-change";function c(e,t={}){const r=i(e);if(!r)throw new Error("[one-screen-scale] element not found");const{mode:c="contain",visualWidth:a=450,origin:l="top center",autoResize:u=!0,injectBaseStyles:f=!0,observeContent:d=!0}=t;let h=1,m=null,w=null,y=null,v=0,p=0,g=null,E=!1,L={w:0,h:0},b=0;const S={width:r.style.width,height:r.style.height,transform:r.style.transform,transformOrigin:r.style.transformOrigin};function C(){const e=r.offsetWidth,t=r.offsetHeight,n=document.documentElement.clientWidth||window.innerWidth,o=window.innerHeight;return L={w:e,h:t},function({sourceWidth:e,sourceHeight:t,targetWidth:n=("undefined"!=typeof window?window.innerWidth:1920),targetHeight:r=("undefined"!=typeof window?window.innerHeight:1080),mode:o="contain",visualWidth:i=450}){if(!e||!t||e<=0||t<=0)return 1;let s;if("fixed-width"===o)s=n>i?i/n:1;else{const o=n/e,i=r/t;s=Math.min(o,i)}return s}({sourceWidth:e,sourceHeight:t,targetWidth:n,targetHeight:o,mode:c,visualWidth:a})}function F(){E=!0;const e=C();if(h=e,function(e,t,n="top center"){const r=i(e);if(!r)return;r.style.transform=`scale(${t})`,r.style.transformOrigin=n;const o=t>0?1/t:1;r.style.setProperty("--one-screen-scale",String(t)),r.style.setProperty("--one-screen-inverse-scale",String(o)),"undefined"!=typeof window&&window.dispatchEvent(new CustomEvent(s,{detail:{scale:t,inverseScale:o,el:r}}))}(r,e,l),"fixed-width"===c&&e>0){const t=`${document.documentElement.clientWidth||window.innerWidth}px`,n=`${Math.round(window.innerHeight/e)}px`;r.style.width!==t&&(r.style.width=t),r.style.height!==n&&(r.style.height=n)}const t=b;return cancelAnimationFrame(p),p=requestAnimationFrame(()=>{t===b&&(E=!1)}),h}function x(){if(E)return;cancelAnimationFrame(v);const e=b;v=requestAnimationFrame(()=>{if(e!==b)return;const t=r.offsetWidth,n=r.offsetHeight;t===L.w&&n===L.h&&r.style.transform||F()})}function A(){F()}return{start:function(){b+=1;const e=b;return E=!1,f&&o(r,c),F(),u&&(m=A,window.addEventListener("resize",m)),d&&"undefined"!=typeof window&&("undefined"!=typeof ResizeObserver&&(g=new ResizeObserver(()=>x()),g.observe(r)),w=e=>{const t=e.target;!t||"IMG"!==t.tagName&&"VIDEO"!==t.tagName&&"IFRAME"!==t.tagName||x()},r.addEventListener("load",w,!0),r.addEventListener("error",w,!0),document.fonts&&document.fonts.ready&&document.fonts.ready.then(()=>{e===b&&x()}).catch(()=>{}),"complete"===document.readyState?x():(y=()=>x(),window.addEventListener("load",y,{once:!0})),requestAnimationFrame(()=>{requestAnimationFrame(()=>x())})),h},stop:function(){b+=1,m&&(window.removeEventListener("resize",m),m=null),w&&(r.removeEventListener("load",w,!0),r.removeEventListener("error",w,!0),w=null),y&&(window.removeEventListener("load",y),y=null),g&&(g.disconnect(),g=null),cancelAnimationFrame(v),cancelAnimationFrame(p),v=0,p=0,f&&function(e){e&&void 0!==e.classList&&e.classList.remove(n.contain,n["fixed-width"])}(r),r.style.width=S.width,r.style.height=S.height,r.style.transform=S.transform,r.style.transformOrigin=S.transformOrigin,r.style.removeProperty("--one-screen-scale"),r.style.removeProperty("--one-screen-inverse-scale")},refresh:F,getScale:()=>h}}function a(e){if(!e||"undefined"==typeof getComputedStyle)return NaN;const t=getComputedStyle(e).getPropertyValue("--one-screen-scale").trim();if(!t)return NaN;const n=parseFloat(t);return n>0?n:NaN}function l(e){if(!e||"undefined"==typeof getComputedStyle)return NaN;const t=getComputedStyle(e).transform;if(!t||"none"===t)return NaN;const n=t.match(/matrix\(([^,]+),\s*[^,]+,\s*[^,]+,\s*([^,]+)/);if(n)return(parseFloat(n[1])+parseFloat(n[2]))/2;const r=t.match(/matrix3d\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\)/);if(r)return(parseFloat(r[1])+parseFloat(r[2]))/2;const o=t.match(/scale\(([^)]+)\)/);if(o){const e=o[1].split(",").map(e=>parseFloat(e.trim()));return e.length>=2?(e[0]+e[1])/2:e[0]}return NaN}function u(e){if(!e)return{scale:1,inverseScale:1};const t=function(e){let t=e;for(;t&&1===t.nodeType;){const e=a(t);if(e>0)return e;t=t.parentElement}for(t=e;t&&1===t.nodeType;){if(!t.__oneScreenCompensate){const e=l(t);if(e>0&&1!==e)return e}t=t.parentElement}return 1}(e),n=t>0?1/t:1;return e.style.transform=`scale(${n})`,e.style.transformOrigin="top left",e.style.width=100*t+"%",e.style.height=100*t+"%",e.style.overflow="visible",e.__oneScreenCompensate=!0,{scale:t,inverseScale:n}}function f(e){return{width:Math.max(1,Math.round(e?.offsetWidth||0)),height:Math.max(1,Math.round(e?.offsetHeight||0))}}function d(e,t){if(!e||"function"!=typeof t)return!1;let n;try{n=t(e)}catch{return!1}if(!n||"function"!=typeof n.resize)return!1;const{width:r,height:o}=f(e);try{return n.resize({width:r,height:o}),!0}catch{return!1}}function h(e){const t="undefined"!=typeof globalThis?globalThis.Chart:null,n=t?.getChart;if("function"!=typeof n)return!1;let r;try{r=n(e)}catch{return!1}if(!r||"function"!=typeof r.resize)return!1;try{return r.resize(),!0}catch{return!1}}function m(e,t){if(!e)return 0;const n=t||("undefined"!=typeof globalThis?globalThis.echarts:null)||null;const r=n?.getInstanceByDom;let o=0;const i=e.querySelectorAll?e.querySelectorAll("canvas"):[];for(const t of i){const n=t.parentElement||t,{width:i,height:s}=f(n);(d(t,r)||d(n,r))&&(o+=1),h(t)&&(o+=1);try{t.dispatchEvent(new CustomEvent("one-screen-scale-canvas-resize",{bubbles:!0,detail:{width:i,height:s,canvas:t,el:e}}))}catch{}}if("function"==typeof r){const t=[e,...e.querySelectorAll("div")];for(const e of t)d(e,r)&&(o+=1)}return o}function w(e={}){return Boolean(e.resizeCanvas||e.echarts||e.echartsLib)}function y(e={}){return"object"==typeof e.echarts?e.echarts:e.echartsLib?e.echartsLib:void 0}function v(e){const t="function"==typeof e?e():e;return t&&"object"==typeof t?t:{}}function p(e,t){let n=0,r=0,o=0,i=!1;const s=()=>{i=!0,cancelAnimationFrame(n),clearInterval(r)},c=()=>{if(i)return;const a=function(e){return e?"undefined"!=typeof HTMLElement&&e instanceof HTMLElement?e:e.current instanceof HTMLElement?e.current:e.value instanceof HTMLElement?e.value:null:null}(e);if(a)return s(),void t(a);o+=1,o<60?n=requestAnimationFrame(c):r||(r=setInterval(c,200))};return c(),s}exports.useCompensate=function(t,n={}){const r=e.useRef(null),o=e.useRef(n);o.current=n;const i=Boolean(n?.resizeCanvas||n?.echarts||n?.echartsLib),c=n&&"object"==typeof n.echarts&&n.echarts||n?.echartsLib||null;return e.useEffect(()=>{let e=null,n=!1;const i=p(t,t=>{n||(e=function(e,t={}){if(!e)throw new Error("[one-screen-scale] compensate element required");const n=w(v(t));let r=0,o=null,i=null,c=[],a=!1;const l=()=>{c.forEach(e=>clearTimeout(e)),c=[]},f=()=>{if(a)return;const n=v(t),{scale:r,inverseScale:o}=u(e);if("function"==typeof n.onRefresh)try{n.onRefresh({scale:r,inverseScale:o,el:e})}catch{}if(w(n)){const r=y(n);0===m(e,r)&&(l(),[50,200].forEach(n=>{const r=setTimeout(()=>{if(a)return;const n=v(t);m(e,y(n))},n);c.push(r)}))}},d=()=>{a||(cancelAnimationFrame(r),r=requestAnimationFrame(()=>{r=0,a||f()}))};return f(),"undefined"!=typeof window&&(window.addEventListener(s,d),window.addEventListener("resize",d)),"undefined"!=typeof ResizeObserver&&(o=new ResizeObserver(d),e.parentElement&&o.observe(e.parentElement),o.observe(e)),n&&"undefined"!=typeof MutationObserver&&(i=new MutationObserver(d),i.observe(e,{childList:!0,subtree:!0})),{refresh:f,stop:()=>{a=!0,cancelAnimationFrame(r),l(),r=0,"undefined"!=typeof window&&(window.removeEventListener(s,d),window.removeEventListener("resize",d)),o?.disconnect(),o=null,i?.disconnect(),i=null,function(e){e&&(e.style.transform="",e.style.transformOrigin="",e.style.width="",e.style.height="",e.style.overflow="",delete e.__oneScreenCompensate)}(e)}}}(t,()=>o.current||{}),r.current=e)});return()=>{n=!0,i(),e?.stop(),r.current=null}},[t,i,c]),{refresh:e.useCallback(()=>{r.current?.refresh()},[])}},exports.useFitScreen=function(t,n={}){const[r,o]=e.useState(1),[i,a]=e.useState(1),l=e.useRef(null),u=e.useRef(n);return u.current=n,e.useEffect(()=>{let e=()=>{},n=!1;const r=p(t,t=>{if(n)return;const r=c(t,u.current);l.current=r;const i=r.start();o(i),a(i>0?1/i:1);const f=e=>{e.detail?.el===t&&(o(e.detail.scale),a(e.detail.inverseScale))};window.addEventListener(s,f),e=()=>{window.removeEventListener(s,f),r.stop(),l.current=null}});return()=>{n=!0,r(),e()}},[t]),{scale:r,inverseScale:i,refresh:e.useCallback(()=>{if(!(t?.current??t)||!l.current)return;const e=l.current.refresh();o(e),a(e>0?1/e:1)},[t])}};
2
2
  //# sourceMappingURL=react.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.cjs.js","sources":["../src/core.js","../src/react.js"],"sourcesContent":["/**\n * 一屏自适应缩放 — 核心算法(框架无关)\n *\n * 两种模式:\n * 'contain' 一屏展示,内容不溢出,用 min(scaleX, scaleY)\n * 'fixed-width' 固定视觉宽度,内容可滚动,反向补高\n */\n\n// ---------- helpers ----------\n\nfunction resolveEl(el) {\n if (!el) return null\n if (typeof el === 'string') return document.querySelector(el)\n if (el instanceof HTMLElement) return el\n // Vue ref / React ref\n if (el.value instanceof HTMLElement) return el.value\n if (el.current instanceof HTMLElement) return el.current\n return null\n}\n\n// ---------- scale calculation ----------\n\nexport function calculateScale({\n sourceWidth,\n sourceHeight,\n targetWidth = (typeof window !== 'undefined' ? window.innerWidth : 1920),\n targetHeight = (typeof window !== 'undefined' ? window.innerHeight : 1080),\n mode = 'contain',\n visualWidth = 450, // fixed-width 模式下的目标视觉宽度\n screenWidth = (typeof window !== 'undefined' ? window.screen.width : 1920), // fixed-width 模式下的设备屏幕宽度\n}) {\n if (!sourceWidth || !sourceHeight || sourceWidth <= 0 || sourceHeight <= 0) return 1\n\n let scale\n\n if (mode === 'fixed-width') {\n if(screenWidth < visualWidth){\n scale = 1\n }else{\n scale = visualWidth / Math.max(targetWidth, screenWidth)\n }\n } else {\n const sx = targetWidth / sourceWidth\n const sy = targetHeight / sourceHeight\n scale = Math.min(sx, sy)\n }\n\n return scale\n}\n\n// ---------- apply / read ----------\n\nexport function applyScale(el, scale, origin = 'top center') {\n const target = resolveEl(el)\n if (!target) return\n target.style.transform = `scale(${scale})`\n target.style.transformOrigin = origin\n}\n\nexport function getPageScale(el) {\n const target = resolveEl(el)\n if (!target) return 1\n\n const style = window.getComputedStyle(target)\n const t = style.transform\n if (!t || t === 'none') return 1\n\n // matrix(a, b, c, d, e, f) — 2d\n const m2 = t.match(/matrix\\(([^,]+),\\s*[^,]+,\\s*[^,]+,\\s*([^,]+)/)\n if (m2) return (parseFloat(m2[1]) + parseFloat(m2[2])) / 2\n\n // matrix3d — 3d\n const m3 = t.match(/matrix3d\\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\\)/)\n if (m3) return (parseFloat(m3[1]) + parseFloat(m3[2])) / 2\n\n // scale(x, y) or scale(s)\n const sm = t.match(/scale\\(([^)]+)\\)/)\n if (sm) {\n const vals = sm[1].split(',').map(v => parseFloat(v.trim()))\n return vals.length >= 2 ? (vals[0] + vals[1]) / 2 : vals[0]\n }\n\n return 1\n}\n\nexport function getInverseScale(el = '.share-page') {\n const s = getPageScale(el)\n return s > 0 ? 1 / s : 1\n}\n\n// ---------- scaler instance ----------\n\nexport function createScaler(el, options = {}) {\n const target = resolveEl(el)\n if (!target) throw new Error('[one-screen-scale] element not found')\n\n const {\n mode = 'contain',\n visualWidth = 450,\n origin = 'top center',\n autoResize = true\n } = options\n\n let currentScale = 1\n let handler = null\n\n function compute() {\n const sw = target.offsetWidth\n const sh = target.offsetHeight\n const tw = window.innerWidth\n const th = window.innerHeight\n\n return calculateScale({\n sourceWidth: sw,\n sourceHeight: sh,\n targetWidth: tw,\n targetHeight: th,\n mode,\n visualWidth,\n screenWidth: window.screen.width\n })\n }\n\n function refresh() {\n const next = compute()\n if (next !== currentScale) {\n currentScale = next\n applyScale(target, next, origin)\n\n // fixed-width 模式:反向补偿高度\n if (mode === 'fixed-width' && next > 0) {\n target.style.width = `${Math.max(window.innerWidth, window.screen.width)}px`\n target.style.height = `${Math.round(window.innerHeight / next)}px`\n }\n }\n return currentScale\n }\n\n function start() {\n refresh()\n if (autoResize) {\n handler = () => refresh()\n window.addEventListener('resize', handler)\n }\n return currentScale\n }\n\n function stop() {\n if (handler) {\n window.removeEventListener('resize', handler)\n handler = null\n }\n }\n\n return { start, stop, refresh, getScale: () => currentScale }\n}\n","/**\n * React hook\n * useFitScreen(ref, options) → { scale, inverseScale, refresh }\n */\nimport { useRef, useState, useEffect, useCallback } from 'react'\nimport { createScaler } from './core.js'\n\nexport function useFitScreen(targetRef, options = {}) {\n const [scale, setScale] = useState(1)\n const [inverseScale, setInverseScale] = useState(1)\n const scalerRef = useRef(null)\n\n useEffect(() => {\n const el = targetRef?.current ?? targetRef\n if (!el) return\n\n const scaler = createScaler(el, options)\n scalerRef.current = scaler\n const s = scaler.start()\n setScale(s)\n setInverseScale(s > 0 ? 1 / s : 1)\n\n const onResize = () => {\n const s = scaler.getScale()\n setScale(s)\n setInverseScale(s > 0 ? 1 / s : 1)\n }\n window.addEventListener('resize', onResize)\n\n return () => {\n window.removeEventListener('resize', onResize)\n scaler.stop()\n scalerRef.current = null\n }\n }, [targetRef])\n\n const refresh = useCallback(() => {\n const el = targetRef?.current ?? targetRef\n if (!el || !scalerRef.current) return\n const s = scalerRef.current.refresh()\n setScale(s)\n setInverseScale(s > 0 ? 1 / s : 1)\n }, [targetRef])\n\n return { scale, inverseScale, refresh }\n}\n"],"names":["resolveEl","el","document","querySelector","HTMLElement","value","current","createScaler","options","target","Error","mode","visualWidth","origin","autoResize","currentScale","handler","compute","sourceWidth","sourceHeight","targetWidth","window","innerWidth","targetHeight","innerHeight","screenWidth","screen","width","scale","Math","max","sx","sy","min","calculateScale","offsetWidth","offsetHeight","refresh","next","style","transform","transformOrigin","applyScale","height","round","start","addEventListener","stop","removeEventListener","getScale","targetRef","setScale","useState","inverseScale","setInverseScale","scalerRef","useRef","useEffect","scaler","s","onResize","useCallback"],"mappings":"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"}
1
+ {"version":3,"file":"react.cjs.js","sources":["../src/baseStyles.js","../src/core.js","../src/compensate.js","../src/react.js"],"sourcesContent":["/**\n * 指令挂载时注入的「适配生效」基础样式。\n *\n * 前提:页面用了 postcss-px-to-viewport(或同类)把设计稿 px 转成 vw。\n *\n * - contain:宽拉满视口 + 最小一屏高,高度由内容撑开\n * - fixed-width:宽高由 refresh 行内补偿,暂不注入\n * - compensate:第三方组件反缩放(抵消页面 scale,ECharts / Element Plus 等)\n */\n\nexport const STYLE_ELEMENT_ID = 'one-screen-scale-base-styles'\n\nexport const BASE_CLASS = {\n contain: 'one-screen-scale--contain',\n 'fixed-width': 'one-screen-scale--fixed-width',\n compensate: 'one-screen-scale--compensate',\n}\n\nconst BASE_CSS = `\n.${BASE_CLASS.contain} {\n width: 100vw;\n min-height: 100vh;\n min-height: 100dvh;\n}\n/* fixed-width:占位 class,样式先不注入 */\n.${BASE_CLASS['fixed-width']} {\n}\n/*\n * 纯 CSS 反缩放(可选)。v-compensate 指令已改为 JS 行内写入同一公式,更稳。\n * ECharts/Canvas:请用 offsetWidth 量布局盒,勿用 getBoundingClientRect。\n */\n.${BASE_CLASS.compensate} {\n transform: scale(var(--one-screen-inverse-scale, 1));\n transform-origin: top left;\n width: calc(100% * var(--one-screen-scale, 1));\n height: calc(100% * var(--one-screen-scale, 1));\n}\n`.trim()\n\n/** 向 document 注入 / 同步基础样式表(已存在则更新内容,便于本地迭代) */\nexport function ensureBaseStyleSheet() {\n if (typeof document === 'undefined') return null\n let styleEl = document.getElementById(STYLE_ELEMENT_ID)\n if (styleEl) {\n styleEl.textContent = BASE_CSS\n return styleEl\n }\n\n styleEl = document.createElement('style')\n styleEl.id = STYLE_ELEMENT_ID\n styleEl.textContent = BASE_CSS\n document.head.appendChild(styleEl)\n return styleEl\n}\n\n/**\n * 给缩放根节点挂上对应模式的 class。\n * @returns {string | null} 本次加上的 class,便于 stop 时移除\n */\nexport function applyBaseStyles(el, mode = 'contain') {\n if (!el || typeof el.classList === 'undefined') return null\n ensureBaseStyleSheet()\n\n const nextClass = BASE_CLASS[mode] || BASE_CLASS.contain\n // 切换模式时清掉另一套页面级 class(不动 compensate)\n ;[BASE_CLASS.contain, BASE_CLASS['fixed-width']].forEach((cls) => {\n if (cls !== nextClass) el.classList.remove(cls)\n })\n el.classList.add(nextClass)\n return nextClass\n}\n\n/** 移除本库注入的页面级基础 class(不含 compensate) */\nexport function removeBaseStyles(el) {\n if (!el || typeof el.classList === 'undefined') return\n el.classList.remove(BASE_CLASS.contain, BASE_CLASS['fixed-width'])\n}\n\n/** 挂上反缩放补偿 class */\nexport function applyCompensateStyles(el) {\n if (!el || typeof el.classList === 'undefined') return null\n ensureBaseStyleSheet()\n el.classList.add(BASE_CLASS.compensate)\n return BASE_CLASS.compensate\n}\n\n/** 移除反缩放补偿 class */\nexport function removeCompensateStyles(el) {\n if (!el || typeof el.classList === 'undefined') return\n el.classList.remove(BASE_CLASS.compensate)\n}\n","/**\n * 一屏自适应缩放 — 核心算法(框架无关)\n *\n * 两种模式:\n * 'contain' 一屏展示,内容不溢出,用 min(scaleX, scaleY)\n * 'fixed-width' 固定视觉宽度,内容可滚动,反向补高\n *\n * 配套前提:H5 使用 postcss-px-to-viewport(或同类)做移动端适配。\n * createScaler / 指令默认会注入基础宽高样式,保证测量与缩放生效。\n *\n * 图片等异步内容会改变 offsetHeight:默认用 ResizeObserver / 图片 load\n * 在尺寸稳定后再 refresh,避免首屏偶发「量矮了 → scale 偏大」。\n */\n\nimport { applyBaseStyles, removeBaseStyles } from './baseStyles.js'\n\n// ---------- helpers ----------\n\nfunction resolveEl(el) {\n if (!el) return null\n if (typeof el === 'string') return document.querySelector(el)\n if (el instanceof HTMLElement) return el\n // Vue ref / React ref\n if (el.value instanceof HTMLElement) return el.value\n if (el.current instanceof HTMLElement) return el.current\n return null\n}\n\n// ---------- scale calculation ----------\n\nexport function calculateScale({\n sourceWidth,\n sourceHeight,\n targetWidth = (typeof window !== 'undefined' ? window.innerWidth : 1920),\n targetHeight = (typeof window !== 'undefined' ? window.innerHeight : 1080),\n mode = 'contain',\n visualWidth = 450, // fixed-width 模式下的目标视觉宽度\n}) {\n if (!sourceWidth || !sourceHeight || sourceWidth <= 0 || sourceHeight <= 0) return 1\n\n let scale\n\n if (mode === 'fixed-width') {\n // 只用视口宽:视口比目标宽才缩小,否则 1:1(保持清晰)\n scale = targetWidth > visualWidth ? visualWidth / targetWidth : 1\n } else {\n const sx = targetWidth / sourceWidth\n const sy = targetHeight / sourceHeight\n scale = Math.min(sx, sy)\n }\n\n return scale\n}\n\n// ---------- apply / read ----------\n\n/** 页面 scale 变化时抛出,供 ECharts.resize / 业务监听 */\nexport const SCALE_CHANGE_EVENT = 'one-screen-scale-change'\n\nexport function applyScale(el, scale, origin = 'top center') {\n const target = resolveEl(el)\n if (!target) return\n target.style.transform = `scale(${scale})`\n target.style.transformOrigin = origin\n // 供业务 / v-compensate 做反缩放(继承到子树)\n const inv = scale > 0 ? 1 / scale : 1\n target.style.setProperty('--one-screen-scale', String(scale))\n target.style.setProperty('--one-screen-inverse-scale', String(inv))\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(SCALE_CHANGE_EVENT, { detail: { scale, inverseScale: inv, el: target } })\n )\n }\n}\n\nexport function getPageScale(el) {\n const target = resolveEl(el)\n if (!target) return 1\n\n const style = window.getComputedStyle(target)\n const t = style.transform\n if (!t || t === 'none') return 1\n\n // matrix(a, b, c, d, e, f) — 2d\n const m2 = t.match(/matrix\\(([^,]+),\\s*[^,]+,\\s*[^,]+,\\s*([^,]+)/)\n if (m2) return (parseFloat(m2[1]) + parseFloat(m2[2])) / 2\n\n // matrix3d — 3d\n const m3 = t.match(/matrix3d\\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\\)/)\n if (m3) return (parseFloat(m3[1]) + parseFloat(m3[2])) / 2\n\n // scale(x, y) or scale(s)\n const sm = t.match(/scale\\(([^)]+)\\)/)\n if (sm) {\n const vals = sm[1].split(',').map(v => parseFloat(v.trim()))\n return vals.length >= 2 ? (vals[0] + vals[1]) / 2 : vals[0]\n }\n\n return 1\n}\n\nexport function getInverseScale(el = '.share-page') {\n const s = getPageScale(el)\n return s > 0 ? 1 / s : 1\n}\n\n// ---------- scaler instance ----------\n\nexport function createScaler(el, options = {}) {\n const target = resolveEl(el)\n if (!target) throw new Error('[one-screen-scale] element not found')\n\n const {\n mode = 'contain',\n visualWidth = 450,\n origin = 'top center',\n autoResize = true,\n /** 是否自动注入模式所需的宽高基础样式,默认 true */\n injectBaseStyles = true,\n /**\n * 内容尺寸变化时自动重算(图片 load、字体、DOM 撑高)。\n * 解决刷新偶发「图未加载完就测量 → scale 偏大」。\n */\n observeContent = true,\n } = options\n\n let currentScale = 1\n let resizeHandler = null\n let loadHandler = null\n let windowLoadHandler = null\n let rafId = 0\n let unlockRaf = 0\n let ro = null\n let refreshing = false\n let lastMeasured = { w: 0, h: 0 }\n // start / stop 各加一,用来丢掉停掉之后才回来的字体、帧回调\n let session = 0\n\n // fixed-width 会改 inline width/height,stop 时还原\n const savedInline = {\n width: target.style.width,\n height: target.style.height,\n transform: target.style.transform,\n transformOrigin: target.style.transformOrigin,\n }\n\n function compute() {\n const sw = target.offsetWidth\n const sh = target.offsetHeight\n const tw = document.documentElement.clientWidth || window.innerWidth\n const th = window.innerHeight\n\n lastMeasured = { w: sw, h: sh }\n\n return calculateScale({\n sourceWidth: sw,\n sourceHeight: sh,\n targetWidth: tw,\n targetHeight: th,\n mode,\n visualWidth,\n })\n }\n\n function refresh() {\n refreshing = true\n const next = compute()\n currentScale = next\n // 始终写入,保证首次 scale=1 时也带上 transform-origin\n applyScale(target, next, origin)\n\n // fixed-width 模式:反向补偿高度(视觉宽固定,布局宽仍用视口宽再缩小)\n if (mode === 'fixed-width' && next > 0) {\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth\n const nextW = `${viewportWidth}px`\n const nextH = `${Math.round(window.innerHeight / next)}px`\n // 值不变不写,避免 ResizeObserver 死循环\n if (target.style.width !== nextW) target.style.width = nextW\n if (target.style.height !== nextH) target.style.height = nextH\n }\n // 等布局提交后再放开,避免 RO 回调里立刻重入\n const token = session\n cancelAnimationFrame(unlockRaf)\n unlockRaf = requestAnimationFrame(() => {\n if (token !== session) return\n refreshing = false\n })\n return currentScale\n }\n\n function scheduleRefresh() {\n if (refreshing) return\n cancelAnimationFrame(rafId)\n const token = session\n rafId = requestAnimationFrame(() => {\n if (token !== session) return\n // 尺寸没变就跳过(fixed-width 改 height 触发的 RO)\n const w = target.offsetWidth\n const h = target.offsetHeight\n if (w === lastMeasured.w && h === lastMeasured.h && target.style.transform) {\n // 视口变化仍需算:由 window.resize 路径直接 refresh\n return\n }\n refresh()\n })\n }\n\n function onWindowResize() {\n refresh()\n }\n\n function start() {\n session += 1\n const token = session\n // 复用同一实例 start 时,上一次 stop 之后留下的锁要清掉\n refreshing = false\n if (injectBaseStyles) {\n applyBaseStyles(target, mode)\n }\n // 注入样式后再量尺寸\n refresh()\n\n if (autoResize) {\n resizeHandler = onWindowResize\n window.addEventListener('resize', resizeHandler)\n }\n\n if (observeContent && typeof window !== 'undefined') {\n // 1) 子树布局尺寸变化(图片解码后撑高最常见)\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => scheduleRefresh())\n ro.observe(target)\n }\n\n // 2) 捕获阶段听内部 img/video 的 load(含后插入的节点)\n loadHandler = (e) => {\n const t = e.target\n if (t && (t.tagName === 'IMG' || t.tagName === 'VIDEO' || t.tagName === 'IFRAME')) {\n scheduleRefresh()\n }\n }\n target.addEventListener('load', loadHandler, true)\n target.addEventListener('error', loadHandler, true)\n\n // 3) 字体就绪。stop 之后 session 变了,这次回调直接丢掉\n if (document.fonts && document.fonts.ready) {\n document.fonts.ready\n .then(() => {\n if (token !== session) return\n scheduleRefresh()\n })\n .catch(() => {})\n }\n\n // 4) 整页资源 load(缓存命中时可能已 complete)\n if (document.readyState === 'complete') {\n scheduleRefresh()\n } else {\n windowLoadHandler = () => scheduleRefresh()\n window.addEventListener('load', windowLoadHandler, { once: true })\n }\n\n // 5) 再等两帧,覆盖首屏同步布局抖动\n requestAnimationFrame(() => {\n requestAnimationFrame(() => scheduleRefresh())\n })\n }\n\n return currentScale\n }\n\n function stop() {\n session += 1\n if (resizeHandler) {\n window.removeEventListener('resize', resizeHandler)\n resizeHandler = null\n }\n if (loadHandler) {\n target.removeEventListener('load', loadHandler, true)\n target.removeEventListener('error', loadHandler, true)\n loadHandler = null\n }\n if (windowLoadHandler) {\n window.removeEventListener('load', windowLoadHandler)\n windowLoadHandler = null\n }\n if (ro) {\n ro.disconnect()\n ro = null\n }\n cancelAnimationFrame(rafId)\n cancelAnimationFrame(unlockRaf)\n rafId = 0\n unlockRaf = 0\n\n if (injectBaseStyles) {\n removeBaseStyles(target)\n }\n target.style.width = savedInline.width\n target.style.height = savedInline.height\n target.style.transform = savedInline.transform\n target.style.transformOrigin = savedInline.transformOrigin\n target.style.removeProperty('--one-screen-scale')\n target.style.removeProperty('--one-screen-inverse-scale')\n }\n\n return { start, stop, refresh, getScale: () => currentScale }\n}\n\nexport {\n applyBaseStyles,\n removeBaseStyles,\n applyCompensateStyles,\n removeCompensateStyles,\n ensureBaseStyleSheet,\n BASE_CLASS,\n} from './baseStyles.js'\n","/**\n * 组件级反缩放补偿(与业务 WinRateChart 手写公式一致):\n * transform: scale(inverse); width/height: 100% * pageScale; origin: top left\n *\n * 只抵消页面 v-fit-screen 的 scale;不处理浏览器 Ctrl+/-。\n */\n\nimport { SCALE_CHANGE_EVENT } from './core.js'\n\n/** 子树 canvas 需要重绘时抛出(挂在每个 <canvas> 上) */\nexport const CANVAS_RESIZE_EVENT = 'one-screen-scale-canvas-resize'\n\n/** @type {null | { getInstanceByDom?: (el: Element) => { resize: Function } | undefined }} */\nlet registeredEcharts = null\n\n/** 业务可注入 echarts 模块(避免插件硬依赖);供 resizeCanvas 探测 */\nexport function setCompensateEcharts(echarts) {\n registeredEcharts = echarts || null\n}\n\nfunction readCssVarScale(el) {\n if (!el || typeof getComputedStyle === 'undefined') return NaN\n const raw = getComputedStyle(el).getPropertyValue('--one-screen-scale').trim()\n if (!raw) return NaN\n const v = parseFloat(raw)\n return v > 0 ? v : NaN\n}\n\nfunction readTransformScale(el) {\n if (!el || typeof getComputedStyle === 'undefined') return NaN\n const t = getComputedStyle(el).transform\n if (!t || t === 'none') return NaN\n\n const m2 = t.match(/matrix\\(([^,]+),\\s*[^,]+,\\s*[^,]+,\\s*([^,]+)/)\n if (m2) return (parseFloat(m2[1]) + parseFloat(m2[2])) / 2\n\n const m3 = t.match(\n /matrix3d\\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\\)/\n )\n if (m3) return (parseFloat(m3[1]) + parseFloat(m3[2])) / 2\n\n const sm = t.match(/scale\\(([^)]+)\\)/)\n if (sm) {\n const vals = sm[1].split(',').map((v) => parseFloat(v.trim()))\n return vals.length >= 2 ? (vals[0] + vals[1]) / 2 : vals[0]\n }\n return NaN\n}\n\n/** 从 fromEl 向上解析页面 scale(跳过已挂补偿的节点自身 transform) */\nexport function resolvePageScale(fromEl) {\n let node = fromEl\n while (node && node.nodeType === 1) {\n const fromVar = readCssVarScale(node)\n if (fromVar > 0) return fromVar\n node = node.parentElement\n }\n\n node = fromEl\n while (node && node.nodeType === 1) {\n if (!node.__oneScreenCompensate) {\n const fromTf = readTransformScale(node)\n if (fromTf > 0 && fromTf !== 1) return fromTf\n }\n node = node.parentElement\n }\n return 1\n}\n\n/**\n * 给槽位内层写入反缩放行内样式。父槽位需有明确宽高。\n * @returns {{ scale: number, inverseScale: number }}\n */\nexport function applyCompensateTransform(el) {\n if (!el) return { scale: 1, inverseScale: 1 }\n const scale = resolvePageScale(el)\n const inverseScale = scale > 0 ? 1 / scale : 1\n el.style.transform = `scale(${inverseScale})`\n el.style.transformOrigin = 'top left'\n el.style.width = `${100 * scale}%`\n el.style.height = `${100 * scale}%`\n el.style.overflow = 'visible'\n el.__oneScreenCompensate = true\n return { scale, inverseScale }\n}\n\nexport function clearCompensateTransform(el) {\n if (!el) return\n el.style.transform = ''\n el.style.transformOrigin = ''\n el.style.width = ''\n el.style.height = ''\n el.style.overflow = ''\n delete el.__oneScreenCompensate\n}\n\nfunction resolveEchartsLib(bindingEcharts) {\n return (\n bindingEcharts ||\n registeredEcharts ||\n (typeof globalThis !== 'undefined' ? globalThis.echarts : null) ||\n null\n )\n}\n\nfunction boxSize(node) {\n const w = Math.max(1, Math.round(node?.offsetWidth || 0))\n const h = Math.max(1, Math.round(node?.offsetHeight || 0))\n return { width: w, height: h }\n}\n\nfunction tryEchartsResize(node, getInst) {\n if (!node || typeof getInst !== 'function') return false\n let inst\n try {\n inst = getInst(node)\n } catch {\n return false\n }\n if (!inst || typeof inst.resize !== 'function') return false\n const { width, height } = boxSize(node)\n try {\n inst.resize({ width, height })\n return true\n } catch {\n return false\n }\n}\n\nfunction tryChartJsResize(canvas) {\n const Chart = typeof globalThis !== 'undefined' ? globalThis.Chart : null\n const getChart = Chart?.getChart\n if (typeof getChart !== 'function') return false\n let chart\n try {\n chart = getChart(canvas)\n } catch {\n return false\n }\n if (!chart || typeof chart.resize !== 'function') return false\n try {\n chart.resize()\n return true\n } catch {\n return false\n }\n}\n\n/**\n * 补偿后通知子树 canvas 重绘:\n * - 探测 ECharts / Chart.js(若已加载)\n * - 每个 <canvas> 派发 CANVAS_RESIZE_EVENT,业务可自行监听重绘\n * 量尺寸用 offsetWidth(勿用 getBoundingClientRect)\n *\n * @returns {number} 成功调用已知图表库 resize 的次数\n */\nexport function resizeCanvasUnder(el, echartsLib) {\n if (!el) return 0\n\n const echarts = resolveEchartsLib(echartsLib)\n const getInst = echarts?.getInstanceByDom\n let count = 0\n\n const canvases = el.querySelectorAll ? el.querySelectorAll('canvas') : []\n for (const canvas of canvases) {\n const host = canvas.parentElement || canvas\n const { width, height } = boxSize(host)\n\n if (tryEchartsResize(canvas, getInst)) count += 1\n else if (tryEchartsResize(host, getInst)) count += 1\n\n if (tryChartJsResize(canvas)) count += 1\n\n try {\n canvas.dispatchEvent(\n new CustomEvent(CANVAS_RESIZE_EVENT, {\n bubbles: true,\n detail: { width, height, canvas, el },\n })\n )\n } catch {\n /* ignore */\n }\n }\n\n // ECharts 常挂在 div 上(不一定已有 canvas)\n if (typeof getInst === 'function') {\n const nodes = [el, ...el.querySelectorAll('div')]\n for (const node of nodes) {\n if (tryEchartsResize(node, getInst)) count += 1\n }\n }\n\n return count\n}\n\n/** @deprecated 请用 resizeCanvasUnder */\nexport function resizeEchartsUnder(el, echartsLib) {\n return resizeCanvasUnder(el, echartsLib)\n}\n\nfunction wantsResizeCanvas(options = {}) {\n return Boolean(\n options.resizeCanvas ||\n options.echarts || // 兼容旧名\n options.echartsLib\n )\n}\n\nfunction resolveBoundEcharts(options = {}) {\n if (typeof options.echarts === 'object') return options.echarts\n if (options.echartsLib) return options.echartsLib\n return undefined\n}\n\n/** options 可以是对象,也可以是返回最新对象的函数(指令 / hook 传 getter 用) */\nfunction readLiveOptions(options) {\n const value = typeof options === 'function' ? options() : options\n return value && typeof value === 'object' ? value : {}\n}\n\n/**\n * @param {HTMLElement} el\n * @param {{\n * resizeCanvas?: boolean,\n * echarts?: boolean | object,\n * echartsLib?: object,\n * onRefresh?: Function\n * } | (() => object)} [options]\n */\nexport function createCompensate(el, options = {}) {\n if (!el) throw new Error('[one-screen-scale] compensate element required')\n\n const initial = readLiveOptions(options)\n const wantResize = wantsResizeCanvas(initial)\n let raf = 0\n let ro = null\n let mo = null\n let retryTimers = []\n let stopped = false\n\n const clearRetries = () => {\n retryTimers.forEach((id) => clearTimeout(id))\n retryTimers = []\n }\n\n const refresh = () => {\n if (stopped) return\n const live = readLiveOptions(options)\n const { scale, inverseScale } = applyCompensateTransform(el)\n if (typeof live.onRefresh === 'function') {\n try {\n live.onRefresh({ scale, inverseScale, el })\n } catch {\n /* user callback */\n }\n }\n if (wantsResizeCanvas(live)) {\n const lib = resolveBoundEcharts(live)\n const n = resizeCanvasUnder(el, lib)\n if (n === 0) {\n clearRetries()\n ;[50, 200].forEach((delay) => {\n const id = setTimeout(() => {\n if (stopped) return\n const next = readLiveOptions(options)\n resizeCanvasUnder(el, resolveBoundEcharts(next))\n }, delay)\n retryTimers.push(id)\n })\n }\n }\n }\n\n const schedule = () => {\n if (stopped) return\n cancelAnimationFrame(raf)\n raf = requestAnimationFrame(() => {\n raf = 0\n if (stopped) return\n refresh()\n })\n }\n\n refresh()\n\n if (typeof window !== 'undefined') {\n window.addEventListener(SCALE_CHANGE_EVENT, schedule)\n window.addEventListener('resize', schedule)\n }\n\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(schedule)\n if (el.parentElement) ro.observe(el.parentElement)\n ro.observe(el)\n }\n\n if (wantResize && typeof MutationObserver !== 'undefined') {\n mo = new MutationObserver(schedule)\n mo.observe(el, { childList: true, subtree: true })\n }\n\n const stop = () => {\n stopped = true\n cancelAnimationFrame(raf)\n clearRetries()\n raf = 0\n if (typeof window !== 'undefined') {\n window.removeEventListener(SCALE_CHANGE_EVENT, schedule)\n window.removeEventListener('resize', schedule)\n }\n ro?.disconnect()\n ro = null\n mo?.disconnect()\n mo = null\n clearCompensateTransform(el)\n }\n\n return { refresh, stop }\n}\n","/**\n * React hooks\n * useFitScreen(ref, options) → { scale, inverseScale, refresh }\n * useCompensate(ref, options) → { refresh } // 对应 Vue v-compensate\n */\nimport { useRef, useState, useEffect, useCallback } from 'react'\nimport { createScaler, SCALE_CHANGE_EVENT } from './core.js'\nimport { createCompensate } from './compensate.js'\n\nfunction resolveElement(targetRef) {\n if (!targetRef) return null\n if (typeof HTMLElement !== 'undefined' && targetRef instanceof HTMLElement) return targetRef\n if (targetRef.current instanceof HTMLElement) return targetRef.current\n if (targetRef.value instanceof HTMLElement) return targetRef.value\n return null\n}\n\n/** ref 第一次 effect 时可能还是空的,等到节点出现再挂。卸载时停掉等待 */\nfunction waitForElement(targetRef, onReady) {\n let raf = 0\n let timer = 0\n let frames = 0\n let settled = false\n\n const finish = () => {\n settled = true\n cancelAnimationFrame(raf)\n clearInterval(timer)\n }\n\n const tick = () => {\n if (settled) return\n const el = resolveElement(targetRef)\n if (el) {\n finish()\n onReady(el)\n return\n }\n frames += 1\n if (frames < 60) raf = requestAnimationFrame(tick)\n else if (!timer) timer = setInterval(tick, 200)\n }\n\n tick()\n return finish\n}\n\nexport function useFitScreen(targetRef, options = {}) {\n const [scale, setScale] = useState(1)\n const [inverseScale, setInverseScale] = useState(1)\n const scalerRef = useRef(null)\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n useEffect(() => {\n let detach = () => {}\n let disposed = false\n\n const cancelWait = waitForElement(targetRef, (el) => {\n if (disposed) return\n const scaler = createScaler(el, optionsRef.current)\n scalerRef.current = scaler\n const s = scaler.start()\n setScale(s)\n setInverseScale(s > 0 ? 1 / s : 1)\n\n const onScale = (event) => {\n if (event.detail?.el !== el) return\n setScale(event.detail.scale)\n setInverseScale(event.detail.inverseScale)\n }\n window.addEventListener(SCALE_CHANGE_EVENT, onScale)\n detach = () => {\n window.removeEventListener(SCALE_CHANGE_EVENT, onScale)\n scaler.stop()\n scalerRef.current = null\n }\n })\n\n return () => {\n disposed = true\n cancelWait()\n detach()\n }\n }, [targetRef])\n\n const refresh = useCallback(() => {\n const el = targetRef?.current ?? targetRef\n if (!el || !scalerRef.current) return\n const s = scalerRef.current.refresh()\n setScale(s)\n setInverseScale(s > 0 ? 1 / s : 1)\n }, [targetRef])\n\n return { scale, inverseScale, refresh }\n}\n\n/**\n * 第三方组件反缩放补偿(对应 Vue `v-compensate`)。\n * 挂在槽位内层 ref 上;父槽位需有明确宽高。\n *\n * @example\n * const innerRef = useRef(null)\n * useCompensate(innerRef, { resizeCanvas: true })\n */\nexport function useCompensate(targetRef, options = {}) {\n const apiRef = useRef(null)\n const optionsRef = useRef(options)\n optionsRef.current = options\n const resizeFlag = Boolean(options?.resizeCanvas || options?.echarts || options?.echartsLib)\n const lib =\n (options && typeof options.echarts === 'object' && options.echarts) ||\n options?.echartsLib ||\n null\n\n useEffect(() => {\n let api = null\n let disposed = false\n\n const cancelWait = waitForElement(targetRef, (el) => {\n if (disposed) return\n api = createCompensate(el, () => optionsRef.current || {})\n apiRef.current = api\n })\n\n return () => {\n disposed = true\n cancelWait()\n api?.stop()\n apiRef.current = null\n }\n }, [targetRef, resizeFlag, lib])\n\n const refresh = useCallback(() => {\n apiRef.current?.refresh()\n }, [])\n\n return { refresh }\n}\n"],"names":["STYLE_ELEMENT_ID","BASE_CLASS","contain","compensate","BASE_CSS","trim","applyBaseStyles","el","mode","classList","document","styleEl","getElementById","textContent","createElement","id","head","appendChild","ensureBaseStyleSheet","nextClass","forEach","cls","remove","add","resolveEl","querySelector","HTMLElement","value","current","SCALE_CHANGE_EVENT","createScaler","options","target","Error","visualWidth","origin","autoResize","injectBaseStyles","observeContent","currentScale","resizeHandler","loadHandler","windowLoadHandler","rafId","unlockRaf","ro","refreshing","lastMeasured","w","h","session","savedInline","width","style","height","transform","transformOrigin","compute","sw","offsetWidth","sh","offsetHeight","tw","documentElement","clientWidth","window","innerWidth","th","innerHeight","sourceWidth","sourceHeight","targetWidth","targetHeight","scale","sx","sy","Math","min","calculateScale","refresh","next","inv","setProperty","String","dispatchEvent","CustomEvent","detail","inverseScale","applyScale","nextW","nextH","round","token","cancelAnimationFrame","requestAnimationFrame","scheduleRefresh","onWindowResize","start","addEventListener","ResizeObserver","observe","e","t","tagName","fonts","ready","then","catch","readyState","once","stop","removeEventListener","disconnect","removeBaseStyles","removeProperty","getScale","readCssVarScale","getComputedStyle","NaN","raw","getPropertyValue","v","parseFloat","readTransformScale","m2","match","m3","sm","vals","split","map","length","applyCompensateTransform","fromEl","node","nodeType","fromVar","parentElement","__oneScreenCompensate","fromTf","resolvePageScale","overflow","boxSize","max","tryEchartsResize","getInst","inst","resize","tryChartJsResize","canvas","Chart","globalThis","getChart","chart","resizeCanvasUnder","echartsLib","echarts","getInstanceByDom","count","canvases","querySelectorAll","host","bubbles","nodes","wantsResizeCanvas","Boolean","resizeCanvas","resolveBoundEcharts","readLiveOptions","waitForElement","targetRef","onReady","raf","timer","frames","settled","finish","clearInterval","tick","resolveElement","setInterval","apiRef","useRef","optionsRef","resizeFlag","lib","useEffect","api","disposed","cancelWait","wantResize","mo","retryTimers","stopped","clearRetries","clearTimeout","live","onRefresh","delay","setTimeout","push","schedule","MutationObserver","childList","subtree","clearCompensateTransform","createCompensate","useCallback","setScale","useState","setInverseScale","scalerRef","detach","scaler","s","onScale","event"],"mappings":"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"}
package/dist/react.d.ts CHANGED
@@ -7,6 +7,25 @@ export interface ScalerOptions {
7
7
  visualWidth?: number
8
8
  origin?: string
9
9
  autoResize?: boolean
10
+ /**
11
+ * 是否自动注入模式所需基础样式(默认 true)
12
+ * - contain: width:100vw; min-height:100vh/100dvh
13
+ * - fixed-width: 暂不注入(宽高由 refresh 行内补偿)
14
+ */
15
+ injectBaseStyles?: boolean
16
+ /**
17
+ * 内容尺寸变化时自动重算(默认 true)
18
+ */
19
+ observeContent?: boolean
20
+ }
21
+
22
+ export interface CompensateOptions {
23
+ /** 补偿后通知子树 canvas 重绘(ECharts / Chart.js / 自定义事件) */
24
+ resizeCanvas?: boolean
25
+ /** @deprecated 请用 resizeCanvas */
26
+ echarts?: boolean | { getInstanceByDom?: (el: Element) => { resize: (opts?: object) => void } | undefined }
27
+ echartsLib?: { getInstanceByDom?: (el: Element) => { resize: (opts?: object) => void } | undefined }
28
+ onRefresh?: (detail: { scale: number; inverseScale: number; el: HTMLElement }) => void
10
29
  }
11
30
 
12
31
  export function useFitScreen(
@@ -17,3 +36,14 @@ export function useFitScreen(
17
36
  inverseScale: number
18
37
  refresh: () => void
19
38
  }
39
+
40
+ /**
41
+ * 对应 Vue `v-compensate`:抵消页面 scale 的组件反缩放。
42
+ * 节点晚于首次 effect 出现时会自动补挂;`resizeCanvas` 变化会重建监听。
43
+ */
44
+ export function useCompensate(
45
+ targetRef: RefObject<HTMLElement | null> | HTMLElement,
46
+ options?: CompensateOptions
47
+ ): {
48
+ refresh: () => void
49
+ }
package/dist/react.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import{useState as e,useRef as n,useEffect as t,useCallback as r}from"react";function i(e){return e?"string"==typeof e?document.querySelector(e):e instanceof HTMLElement?e:e.value instanceof HTMLElement?e.value:e.current instanceof HTMLElement?e.current:null:null}function o(e,n={}){const t=i(e);if(!t)throw new Error("[one-screen-scale] element not found");const{mode:r="contain",visualWidth:o=450,origin:s="top center",autoResize:c=!0}=n;let d=1,u=null;function w(){return function({sourceWidth:e,sourceHeight:n,targetWidth:t=("undefined"!=typeof window?window.innerWidth:1920),targetHeight:r=("undefined"!=typeof window?window.innerHeight:1080),mode:i="contain",visualWidth:o=450,screenWidth:s=("undefined"!=typeof window?window.screen.width:1920)}){if(!e||!n||e<=0||n<=0)return 1;let c;if("fixed-width"===i)c=s<o?1:o/Math.max(t,s);else{const i=t/e,o=r/n;c=Math.min(i,o)}return c}({sourceWidth:t.offsetWidth,sourceHeight:t.offsetHeight,targetWidth:window.innerWidth,targetHeight:window.innerHeight,mode:r,visualWidth:o,screenWidth:window.screen.width})}function f(){const e=w();return e!==d&&(d=e,function(e,n,t="top center"){const r=i(e);r&&(r.style.transform=`scale(${n})`,r.style.transformOrigin=t)}(t,e,s),"fixed-width"===r&&e>0&&(t.style.width=`${Math.max(window.innerWidth,window.screen.width)}px`,t.style.height=`${Math.round(window.innerHeight/e)}px`)),d}return{start:function(){return f(),c&&(u=()=>f(),window.addEventListener("resize",u)),d},stop:function(){u&&(window.removeEventListener("resize",u),u=null)},refresh:f,getScale:()=>d}}function s(i,s={}){const[c,d]=e(1),[u,w]=e(1),f=n(null);t(()=>{const e=i?.current??i;if(!e)return;const n=o(e,s);f.current=n;const t=n.start();d(t),w(t>0?1/t:1);const r=()=>{const e=n.getScale();d(e),w(e>0?1/e:1)};return window.addEventListener("resize",r),()=>{window.removeEventListener("resize",r),n.stop(),f.current=null}},[i]);return{scale:c,inverseScale:u,refresh:r(()=>{if(!(i?.current??i)||!f.current)return;const e=f.current.refresh();d(e),w(e>0?1/e:1)},[i])}}export{s as useFitScreen};
1
+ import{useState as e,useRef as t,useEffect as n,useCallback as r}from"react";const o="one-screen-scale-base-styles",i={contain:"one-screen-scale--contain","fixed-width":"one-screen-scale--fixed-width",compensate:"one-screen-scale--compensate"},s=`\n.${i.contain} {\n width: 100vw;\n min-height: 100vh;\n min-height: 100dvh;\n}\n/* fixed-width:占位 class,样式先不注入 */\n.${i["fixed-width"]} {\n}\n/*\n * 纯 CSS 反缩放(可选)。v-compensate 指令已改为 JS 行内写入同一公式,更稳。\n * ECharts/Canvas:请用 offsetWidth 量布局盒,勿用 getBoundingClientRect。\n */\n.${i.compensate} {\n transform: scale(var(--one-screen-inverse-scale, 1));\n transform-origin: top left;\n width: calc(100% * var(--one-screen-scale, 1));\n height: calc(100% * var(--one-screen-scale, 1));\n}\n`.trim();function c(e,t="contain"){if(!e||void 0===e.classList)return null;!function(){if("undefined"==typeof document)return null;let e=document.getElementById(o);e?e.textContent=s:(e=document.createElement("style"),e.id=o,e.textContent=s,document.head.appendChild(e))}();const n=i[t]||i.contain;return[i.contain,i["fixed-width"]].forEach(t=>{t!==n&&e.classList.remove(t)}),e.classList.add(n),n}function a(e){return e?"string"==typeof e?document.querySelector(e):e instanceof HTMLElement?e:e.value instanceof HTMLElement?e.value:e.current instanceof HTMLElement?e.current:null:null}const l="one-screen-scale-change";function u(e,t={}){const n=a(e);if(!n)throw new Error("[one-screen-scale] element not found");const{mode:r="contain",visualWidth:o=450,origin:s="top center",autoResize:u=!0,injectBaseStyles:f=!0,observeContent:d=!0}=t;let h=1,m=null,w=null,y=null,v=0,p=0,g=null,E=!1,L={w:0,h:0},b=0;const S={width:n.style.width,height:n.style.height,transform:n.style.transform,transformOrigin:n.style.transformOrigin};function C(){const e=n.offsetWidth,t=n.offsetHeight,i=document.documentElement.clientWidth||window.innerWidth,s=window.innerHeight;return L={w:e,h:t},function({sourceWidth:e,sourceHeight:t,targetWidth:n=("undefined"!=typeof window?window.innerWidth:1920),targetHeight:r=("undefined"!=typeof window?window.innerHeight:1080),mode:o="contain",visualWidth:i=450}){if(!e||!t||e<=0||t<=0)return 1;let s;if("fixed-width"===o)s=n>i?i/n:1;else{const o=n/e,i=r/t;s=Math.min(o,i)}return s}({sourceWidth:e,sourceHeight:t,targetWidth:i,targetHeight:s,mode:r,visualWidth:o})}function F(){E=!0;const e=C();if(h=e,function(e,t,n="top center"){const r=a(e);if(!r)return;r.style.transform=`scale(${t})`,r.style.transformOrigin=n;const o=t>0?1/t:1;r.style.setProperty("--one-screen-scale",String(t)),r.style.setProperty("--one-screen-inverse-scale",String(o)),"undefined"!=typeof window&&window.dispatchEvent(new CustomEvent(l,{detail:{scale:t,inverseScale:o,el:r}}))}(n,e,s),"fixed-width"===r&&e>0){const t=`${document.documentElement.clientWidth||window.innerWidth}px`,r=`${Math.round(window.innerHeight/e)}px`;n.style.width!==t&&(n.style.width=t),n.style.height!==r&&(n.style.height=r)}const t=b;return cancelAnimationFrame(p),p=requestAnimationFrame(()=>{t===b&&(E=!1)}),h}function x(){if(E)return;cancelAnimationFrame(v);const e=b;v=requestAnimationFrame(()=>{if(e!==b)return;const t=n.offsetWidth,r=n.offsetHeight;t===L.w&&r===L.h&&n.style.transform||F()})}function A(){F()}return{start:function(){b+=1;const e=b;return E=!1,f&&c(n,r),F(),u&&(m=A,window.addEventListener("resize",m)),d&&"undefined"!=typeof window&&("undefined"!=typeof ResizeObserver&&(g=new ResizeObserver(()=>x()),g.observe(n)),w=e=>{const t=e.target;!t||"IMG"!==t.tagName&&"VIDEO"!==t.tagName&&"IFRAME"!==t.tagName||x()},n.addEventListener("load",w,!0),n.addEventListener("error",w,!0),document.fonts&&document.fonts.ready&&document.fonts.ready.then(()=>{e===b&&x()}).catch(()=>{}),"complete"===document.readyState?x():(y=()=>x(),window.addEventListener("load",y,{once:!0})),requestAnimationFrame(()=>{requestAnimationFrame(()=>x())})),h},stop:function(){b+=1,m&&(window.removeEventListener("resize",m),m=null),w&&(n.removeEventListener("load",w,!0),n.removeEventListener("error",w,!0),w=null),y&&(window.removeEventListener("load",y),y=null),g&&(g.disconnect(),g=null),cancelAnimationFrame(v),cancelAnimationFrame(p),v=0,p=0,f&&function(e){e&&void 0!==e.classList&&e.classList.remove(i.contain,i["fixed-width"])}(n),n.style.width=S.width,n.style.height=S.height,n.style.transform=S.transform,n.style.transformOrigin=S.transformOrigin,n.style.removeProperty("--one-screen-scale"),n.style.removeProperty("--one-screen-inverse-scale")},refresh:F,getScale:()=>h}}function f(e){if(!e||"undefined"==typeof getComputedStyle)return NaN;const t=getComputedStyle(e).getPropertyValue("--one-screen-scale").trim();if(!t)return NaN;const n=parseFloat(t);return n>0?n:NaN}function d(e){if(!e||"undefined"==typeof getComputedStyle)return NaN;const t=getComputedStyle(e).transform;if(!t||"none"===t)return NaN;const n=t.match(/matrix\(([^,]+),\s*[^,]+,\s*[^,]+,\s*([^,]+)/);if(n)return(parseFloat(n[1])+parseFloat(n[2]))/2;const r=t.match(/matrix3d\(([^,]+),[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,([^,]+)\)/);if(r)return(parseFloat(r[1])+parseFloat(r[2]))/2;const o=t.match(/scale\(([^)]+)\)/);if(o){const e=o[1].split(",").map(e=>parseFloat(e.trim()));return e.length>=2?(e[0]+e[1])/2:e[0]}return NaN}function h(e){if(!e)return{scale:1,inverseScale:1};const t=function(e){let t=e;for(;t&&1===t.nodeType;){const e=f(t);if(e>0)return e;t=t.parentElement}for(t=e;t&&1===t.nodeType;){if(!t.__oneScreenCompensate){const e=d(t);if(e>0&&1!==e)return e}t=t.parentElement}return 1}(e),n=t>0?1/t:1;return e.style.transform=`scale(${n})`,e.style.transformOrigin="top left",e.style.width=100*t+"%",e.style.height=100*t+"%",e.style.overflow="visible",e.__oneScreenCompensate=!0,{scale:t,inverseScale:n}}function m(e){return{width:Math.max(1,Math.round(e?.offsetWidth||0)),height:Math.max(1,Math.round(e?.offsetHeight||0))}}function w(e,t){if(!e||"function"!=typeof t)return!1;let n;try{n=t(e)}catch{return!1}if(!n||"function"!=typeof n.resize)return!1;const{width:r,height:o}=m(e);try{return n.resize({width:r,height:o}),!0}catch{return!1}}function y(e){const t="undefined"!=typeof globalThis?globalThis.Chart:null,n=t?.getChart;if("function"!=typeof n)return!1;let r;try{r=n(e)}catch{return!1}if(!r||"function"!=typeof r.resize)return!1;try{return r.resize(),!0}catch{return!1}}function v(e,t){if(!e)return 0;const n=t||("undefined"!=typeof globalThis?globalThis.echarts:null)||null;const r=n?.getInstanceByDom;let o=0;const i=e.querySelectorAll?e.querySelectorAll("canvas"):[];for(const t of i){const n=t.parentElement||t,{width:i,height:s}=m(n);(w(t,r)||w(n,r))&&(o+=1),y(t)&&(o+=1);try{t.dispatchEvent(new CustomEvent("one-screen-scale-canvas-resize",{bubbles:!0,detail:{width:i,height:s,canvas:t,el:e}}))}catch{}}if("function"==typeof r){const t=[e,...e.querySelectorAll("div")];for(const e of t)w(e,r)&&(o+=1)}return o}function p(e={}){return Boolean(e.resizeCanvas||e.echarts||e.echartsLib)}function g(e={}){return"object"==typeof e.echarts?e.echarts:e.echartsLib?e.echartsLib:void 0}function E(e){const t="function"==typeof e?e():e;return t&&"object"==typeof t?t:{}}function L(e,t){let n=0,r=0,o=0,i=!1;const s=()=>{i=!0,cancelAnimationFrame(n),clearInterval(r)},c=()=>{if(i)return;const a=function(e){return e?"undefined"!=typeof HTMLElement&&e instanceof HTMLElement?e:e.current instanceof HTMLElement?e.current:e.value instanceof HTMLElement?e.value:null:null}(e);if(a)return s(),void t(a);o+=1,o<60?n=requestAnimationFrame(c):r||(r=setInterval(c,200))};return c(),s}function b(o,i={}){const[s,c]=e(1),[a,f]=e(1),d=t(null),h=t(i);h.current=i,n(()=>{let e=()=>{},t=!1;const n=L(o,n=>{if(t)return;const r=u(n,h.current);d.current=r;const o=r.start();c(o),f(o>0?1/o:1);const i=e=>{e.detail?.el===n&&(c(e.detail.scale),f(e.detail.inverseScale))};window.addEventListener(l,i),e=()=>{window.removeEventListener(l,i),r.stop(),d.current=null}});return()=>{t=!0,n(),e()}},[o]);return{scale:s,inverseScale:a,refresh:r(()=>{if(!(o?.current??o)||!d.current)return;const e=d.current.refresh();c(e),f(e>0?1/e:1)},[o])}}function S(e,o={}){const i=t(null),s=t(o);s.current=o;const c=Boolean(o?.resizeCanvas||o?.echarts||o?.echartsLib),a=o&&"object"==typeof o.echarts&&o.echarts||o?.echartsLib||null;n(()=>{let t=null,n=!1;const r=L(e,e=>{n||(t=function(e,t={}){if(!e)throw new Error("[one-screen-scale] compensate element required");const n=p(E(t));let r=0,o=null,i=null,s=[],c=!1;const a=()=>{s.forEach(e=>clearTimeout(e)),s=[]},u=()=>{if(c)return;const n=E(t),{scale:r,inverseScale:o}=h(e);if("function"==typeof n.onRefresh)try{n.onRefresh({scale:r,inverseScale:o,el:e})}catch{}if(p(n)){const r=g(n);0===v(e,r)&&(a(),[50,200].forEach(n=>{const r=setTimeout(()=>{if(c)return;const n=E(t);v(e,g(n))},n);s.push(r)}))}},f=()=>{c||(cancelAnimationFrame(r),r=requestAnimationFrame(()=>{r=0,c||u()}))};return u(),"undefined"!=typeof window&&(window.addEventListener(l,f),window.addEventListener("resize",f)),"undefined"!=typeof ResizeObserver&&(o=new ResizeObserver(f),e.parentElement&&o.observe(e.parentElement),o.observe(e)),n&&"undefined"!=typeof MutationObserver&&(i=new MutationObserver(f),i.observe(e,{childList:!0,subtree:!0})),{refresh:u,stop:()=>{c=!0,cancelAnimationFrame(r),a(),r=0,"undefined"!=typeof window&&(window.removeEventListener(l,f),window.removeEventListener("resize",f)),o?.disconnect(),o=null,i?.disconnect(),i=null,function(e){e&&(e.style.transform="",e.style.transformOrigin="",e.style.width="",e.style.height="",e.style.overflow="",delete e.__oneScreenCompensate)}(e)}}}(e,()=>s.current||{}),i.current=t)});return()=>{n=!0,r(),t?.stop(),i.current=null}},[e,c,a]);return{refresh:r(()=>{i.current?.refresh()},[])}}export{S as useCompensate,b as useFitScreen};
2
2
  //# sourceMappingURL=react.esm.js.map