vfit 1.0.0 → 1.0.3

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/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # vfit
2
2
 
3
+ 官网:https://web-vfit.netlify.app
4
+
5
+ 作者:一颗烂土豆
6
+
3
7
  Vue 3 的轻量缩放与定位解决方案。通过插件提供全局缩放值,并内置 `FitContainer` 组件,让页面元素在不同分辨率下保持比例与位置一致。
4
8
 
5
9
  ## 安装与初始化
@@ -13,7 +17,7 @@ npm i vfit
13
17
  import { createFitScale } from 'vfit'
14
18
  import 'vfit/style.css'
15
19
 
16
- app.use(createFitScale({ target: '#app', designHeight: 1080, scaleMode: 'auto' }))
20
+ app.use(createFitScale({ target: '#app', designHeight: 1080, designWidth: 1920, scaleMode: 'auto' }))
17
21
  ```
18
22
 
19
23
  ## 快速上手
@@ -63,13 +67,14 @@ app.use(createFitScale({ target: '#app', designHeight: 1080, scaleMode: 'auto' }
63
67
 
64
68
  ## API 精简版
65
69
 
66
- - `createFitScale({ target?, designHeight?, scaleMode? })`
70
+ - `createFitScale({ target?, designHeight?, designWidth?, scaleMode? })`
67
71
  - `target`:监听缩放的容器(默认 `#app`)
68
72
  - `designHeight`:设计稿高度(默认 `1080`)
73
+ - `designWidth`:设计稿宽度(默认 `1920`)
69
74
  - `scaleMode`:`'height' | 'width' | 'auto'`(默认 `auto`)
70
75
  - `height`:按高度缩放,比例为 `容器高度 / 设计稿高度`
71
- - `width`:按宽度缩放,比例为 `容器宽度 / 1920`(与之前逻辑一致)
72
- - `auto`:根据容器宽高比与设计比(`1920 / 设计稿高度`)自动选择按宽或按高
76
+ - `width`:按宽度缩放,比例为 `容器宽度 / 设计稿宽度`
77
+ - `auto`:根据容器宽高比与设计比(`设计稿宽度 / 设计稿高度`)自动选择按宽或按高
73
78
  - `useFitScale()`:在组件内获取当前缩放值 `Ref<number>`
74
79
  - `FitContainer` 组件属性:
75
80
  - `top/bottom/left/right?: number`
@@ -78,6 +83,6 @@ app.use(createFitScale({ target: '#app', designHeight: 1080, scaleMode: 'auto' }
78
83
 
79
84
  ## 小贴士
80
85
 
81
- - 使用 `right` 时,缩放原点为右上角(更易实现右侧对齐元素)
82
- - 同时设置 `bottom` 与 `right` 时,原点为右下角,对齐更稳定
83
- - 首次接入时,务必引入样式:`import 'vfit/style.css'`
86
+ - 使用 `unit='px'` 时,`top/left` 随缩放变化,`right/bottom` 保持实际像素距离不变
87
+ - 使用 `right` 时,缩放原点为右上角;同时设置 `bottom` 与 `right` 时为右下角
88
+ - 首次接入时,务必引入样式:`import 'vfit/style.css'`
@@ -1,5 +1,5 @@
1
1
  import { defineComponent, reactive, computed, inject, ref, watch, createElementBlock, openBlock, normalizeStyle, renderSlot } from "vue";
2
- function observeScale(target, designHeight, onScale, scaleMode = "auto") {
2
+ function observeScale(target, designHeight, onScale, scaleMode = "auto", designWidth = 1920) {
3
3
  const observer = new ResizeObserver((entries) => {
4
4
  for (const entry of entries) {
5
5
  const rectHeight = entry.contentRect.height;
@@ -8,11 +8,11 @@ function observeScale(target, designHeight, onScale, scaleMode = "auto") {
8
8
  if (scaleMode === "height") {
9
9
  scaleVal = rectHeight / designHeight;
10
10
  } else if (scaleMode === "width") {
11
- scaleVal = rectWidth / 1920 * 0.98;
11
+ scaleVal = rectWidth / designWidth;
12
12
  } else {
13
- const designRatio = 1920 / designHeight;
13
+ const designRatio = designWidth / designHeight;
14
14
  if (rectWidth / rectHeight < designRatio) {
15
- scaleVal = rectWidth / 1920 * 0.98;
15
+ scaleVal = rectWidth / designWidth;
16
16
  } else {
17
17
  scaleVal = rectHeight / designHeight;
18
18
  }
@@ -61,7 +61,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
61
61
  if (props.unit === "%") {
62
62
  position[key] = val == void 0 ? "auto" : `${val}${props.unit}`;
63
63
  } else {
64
- position[key] = val == void 0 ? "auto" : `${val * s}${props.unit}`;
64
+ const needScale = key === "left" || key === "top";
65
+ position[key] = val == void 0 ? "auto" : `${needScale ? val * s : val}${props.unit}`;
65
66
  }
66
67
  });
67
68
  }, { immediate: true });
@@ -82,7 +83,7 @@ const _export_sfc = (sfc, props) => {
82
83
  }
83
84
  return target;
84
85
  };
85
- const FitContainer = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-1954a495"]]);
86
+ const FitContainer = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-1b23da3b"]]);
86
87
  const FitScaleKey = Symbol("FitScale");
87
88
  function createFitScale(options = {}) {
88
89
  const fitScale = ref(1);
@@ -92,7 +93,7 @@ function createFitScale(options = {}) {
92
93
  const target = rootEl || document.querySelector("#app");
93
94
  observeScale(target, options.designHeight ?? 1080, (v) => {
94
95
  fitScale.value = v;
95
- }, options.scaleMode ?? "auto");
96
+ }, options.scaleMode ?? "auto", options.designWidth ?? 1920);
96
97
  app.provide(FitScaleKey, fitScale);
97
98
  app.config.globalProperties.$fitScale = fitScale;
98
99
  app.component("FitContainer", FitContainer);
@@ -1 +1 @@
1
- (function(t,e){typeof exports==="object"&&typeof module!=="undefined"?e(exports,require("vue")):typeof define==="function"&&define.amd?define(["exports","vue"],e):(t=typeof globalThis!=="undefined"?globalThis:t||self,e(t.FitScale={},t.Vue))})(this,function(t,e){"use strict";function o(t,e,o,n="auto"){const i=new ResizeObserver(t=>{for(const i of t){const t=i.contentRect.height;const r=i.contentRect.width;let c;if(n==="height"){c=t/e}else if(n==="width"){c=r/1920*.98}else{const o=1920/e;if(r/t<o){c=r/1920*.98}else{c=t/e}}o(c)}});i.observe(t);return i}const n=e.defineComponent({__name:"FitContainer",props:{scale:{type:Number,default:0},top:{type:Number},bottom:{type:Number},left:{type:Number},right:{type:Number},unit:{type:String,default:"px"},z:{type:Number,default:300}},setup(t){const o=e.reactive({scale:`scale(1)`,top:"auto",bottom:"auto",left:"auto",right:"auto"});const n=t;const i=e.computed(()=>{const t=n.right!==void 0;const e=n.bottom!==void 0;if(t&&e)return"100% 100%";if(t)return"100% 0";if(e)return"0 100%";return"0 0"});const r=e.inject(c,e.ref(1));e.watch([()=>n.scale,r],()=>{const t=n.scale&&n.scale>0?n.scale:(r==null?void 0:r.value)??1;o.scale=`scale(${t})`;const e=["top","bottom","left","right"];e.forEach(e=>{const i=n[e];if(n.unit==="%"){o[e]=i==void 0?"auto":`${i}${n.unit}`}else{o[e]=i==void 0?"auto":`${i*t}${n.unit}`}})},{immediate:true});return(t,r)=>(e.openBlock(),e.createElementBlock("div",{class:"fit-container",style:e.normalizeStyle({transform:o.scale,transformOrigin:i.value,top:o.top,bottom:o.bottom,left:o.left,right:o.right,zIndex:n.z})},[e.renderSlot(t.$slots,"default",{},void 0,true)],4))}});const i=(t,e)=>{const o=t.__vccOpts||t;for(const[n,i]of e){o[n]=i}return o};const r=i(n,[["__scopeId","data-v-1954a495"]]);const c=Symbol("FitScale");function s(t={}){const n=e.ref(1);return{install(e){const i=typeof t.target==="string"?document.querySelector(t.target):t.target;const s=i||document.querySelector("#app");o(s,t.designHeight??1080,t=>{n.value=t},t.scaleMode??"auto");e.provide(c,n);e.config.globalProperties.$fitScale=n;e.component("FitContainer",r)}}}function a(){const t=e.inject(c,e.ref(1));return t}t.FitContainer=r;t.FitScaleKey=c;t.createFitScale=s;t.useFitScale=a;Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
1
+ (function(t,e){typeof exports==="object"&&typeof module!=="undefined"?e(exports,require("vue")):typeof define==="function"&&define.amd?define(["exports","vue"],e):(t=typeof globalThis!=="undefined"?globalThis:t||self,e(t.FitScale={},t.Vue))})(this,function(t,e){"use strict";function o(t,e,o,n="auto",i=1920){const r=new ResizeObserver(t=>{for(const r of t){const t=r.contentRect.height;const c=r.contentRect.width;let s;if(n==="height"){s=t/e}else if(n==="width"){s=c/i}else{const o=i/e;if(c/t<o){s=c/i}else{s=t/e}}o(s)}});r.observe(t);return r}const n=e.defineComponent({__name:"FitContainer",props:{scale:{type:Number,default:0},top:{type:Number},bottom:{type:Number},left:{type:Number},right:{type:Number},unit:{type:String,default:"px"},z:{type:Number,default:300}},setup(t){const o=e.reactive({scale:`scale(1)`,top:"auto",bottom:"auto",left:"auto",right:"auto"});const n=t;const i=e.computed(()=>{const t=n.right!==void 0;const e=n.bottom!==void 0;if(t&&e)return"100% 100%";if(t)return"100% 0";if(e)return"0 100%";return"0 0"});const r=e.inject(c,e.ref(1));e.watch([()=>n.scale,r],()=>{const t=n.scale&&n.scale>0?n.scale:(r==null?void 0:r.value)??1;o.scale=`scale(${t})`;const e=["top","bottom","left","right"];e.forEach(e=>{const i=n[e];if(n.unit==="%"){o[e]=i==void 0?"auto":`${i}${n.unit}`}else{const r=e==="left"||e==="top";o[e]=i==void 0?"auto":`${r?i*t:i}${n.unit}`}})},{immediate:true});return(t,r)=>(e.openBlock(),e.createElementBlock("div",{class:"fit-container",style:e.normalizeStyle({transform:o.scale,transformOrigin:i.value,top:o.top,bottom:o.bottom,left:o.left,right:o.right,zIndex:n.z})},[e.renderSlot(t.$slots,"default",{},void 0,true)],4))}});const i=(t,e)=>{const o=t.__vccOpts||t;for(const[n,i]of e){o[n]=i}return o};const r=i(n,[["__scopeId","data-v-1b23da3b"]]);const c=Symbol("FitScale");function s(t={}){const n=e.ref(1);return{install(e){const i=typeof t.target==="string"?document.querySelector(t.target):t.target;const s=i||document.querySelector("#app");o(s,t.designHeight??1080,t=>{n.value=t},t.scaleMode??"auto",t.designWidth??1920);e.provide(c,n);e.config.globalProperties.$fitScale=n;e.component("FitContainer",r)}}}function l(){const t=e.inject(c,e.ref(1));return t}t.FitContainer=r;t.FitScaleKey=c;t.createFitScale=s;t.useFitScale=l;Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export declare const FitScaleKey: unique symbol;
4
4
  export type FitScaleOptions = {
5
5
  target?: string | HTMLElement;
6
6
  designHeight?: number;
7
+ designWidth?: number;
7
8
  scaleMode?: 'height' | 'width' | 'auto';
8
9
  };
9
10
  export declare function createFitScale(options?: FitScaleOptions): {
package/dist/scale.d.ts CHANGED
@@ -1 +1 @@
1
- export declare function observeScale(target: HTMLElement, designHeight: number, onScale: (scale: number) => void, scaleMode?: 'height' | 'width' | 'auto'): ResizeObserver;
1
+ export declare function observeScale(target: HTMLElement, designHeight: number, onScale: (scale: number) => void, scaleMode?: 'height' | 'width' | 'auto', designWidth?: number): ResizeObserver;
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .fit-container[data-v-1954a495]{position:absolute;transform-origin:0 0;z-index:300;will-change:transform}
1
+ .fit-container[data-v-1b23da3b]{position:absolute;transform-origin:0 0;z-index:300;will-change:transform}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vfit",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "A tiny Vue 3 plugin to auto-fit UI scale based on container size, plus a FitContainer component for easy positioning.",
5
5
  "keywords": [
6
6
  "vue3",
@@ -13,6 +13,7 @@
13
13
  "vue-plugin"
14
14
  ],
15
15
  "license": "MIT",
16
+ "homepage": "https://web-vfit.netlify.app",
16
17
  "type": "module",
17
18
  "main": "dist/fitscale.umd.js",
18
19
  "module": "dist/fitscale.es.js",
@@ -29,15 +30,22 @@
29
30
  "README.md"
30
31
  ],
31
32
  "scripts": {
32
- "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.json"
33
+ "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.json",
34
+ "docs:dev": "vitepress dev docs",
35
+ "docs:build": "vitepress build docs",
36
+ "docs:preview": "vitepress preview docs"
37
+ },
38
+ "pnpm": {
39
+ "overrides": {}
33
40
  },
34
41
  "peerDependencies": {
35
42
  "vue": ">=3.3.0"
36
43
  },
37
44
  "devDependencies": {
38
45
  "@vitejs/plugin-vue": "^5.0.4",
46
+ "terser": "^5.31.0",
39
47
  "typescript": "^5.6.3",
40
48
  "vite": "^5.4.0",
41
- "terser": "^5.31.0"
49
+ "vitepress": "^1.6.4"
42
50
  }
43
- }
51
+ }