video-split-screen 1.0.1

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 ADDED
@@ -0,0 +1,123 @@
1
+ # video-split-screen
2
+
3
+ Vue 3 视频分屏组件(VideoSplitScreen)——可发布到 npm 的插件包。
4
+
5
+ 当前包版本: `1.0.1`
6
+
7
+ 安装(npm)
8
+
9
+ ```bash
10
+ npm install video-split-screen
11
+ # or
12
+ yarn add video-split-screen
13
+ ```
14
+
15
+ 快速使用(全局注册)
16
+
17
+ ```ts
18
+ import { createApp } from 'vue'
19
+ import App from './App.vue'
20
+ import VideoSplitScreen from 'video-split-screen'
21
+
22
+ const app = createApp(App)
23
+ app.use(VideoSplitScreen)
24
+ app.mount('#app')
25
+ ```
26
+
27
+ 按需导入(命名导出)
28
+
29
+ ```ts
30
+ import { VideoGridLayout } from 'video-split-screen'
31
+ ```
32
+
33
+ 样式
34
+
35
+ 包内置一份默认样式,构建时会产出 `dist/style.css`。如果你全局注册插件(`app.use(...)`)示例项目会自动引入样式;也可以按需手动引入:
36
+
37
+ ```ts
38
+ import 'video-split-screen/dist/style.css'
39
+ ```
40
+
41
+ 主要 Props(VideoGridLayout)
42
+
43
+ - `videos: VideoItem[]` — 视频数组(必填)
44
+ - `layout?: LayoutType` — 布局类型('1'|'2'|'3'|'4'|'6'|'7'|'8'|'9'|'10'|'13'|'16'),默认 `'1'`
45
+ - `availableLayouts?: LayoutType[]` — 可选显示的布局按钮列表
46
+ - `showToolbar?: boolean` — 是否显示工具栏,默认 `true`
47
+ - `width?: string` — 宽度(任意 CSS 长度,例如 `100%`, `800px`)
48
+ - `height?: string` — 高度(任意 CSS 长度,例如 `70vh`, `600px`)
49
+ - `placeholderText?: string | (index: number) => string` — 全局占位文本或按索引生成文本的函数
50
+ - `placeholders?: Array<string|number>` — 按索引覆盖占位符(可单独修改某些格子)
51
+
52
+ 占位符规则(优先级)
53
+
54
+ 1. `placeholders[index]`(若存在)
55
+ 2. `placeholderText`(若为函数则调用函数并传入视觉索引;若为字符串则直接使用)
56
+ 3. 回退为视觉索引 + 1(按从左到右、从上到下的视觉顺序编号)
57
+
58
+ 如何发布到 npm(示例)
59
+
60
+ 1. 在 `video-split-screen-package` 目录确认 `package.json` 已填写 `name`, `version`, `repository` 等字段。
61
+ 2. 构建并生成类型声明:
62
+
63
+ ```bash
64
+ cd video-split-screen-package
65
+ npm install
66
+ npm run build
67
+ npm run build:types
68
+ ```
69
+
70
+ 3. 登录 / 设置 token(在你的本地环境或 CI):
71
+
72
+ ```bash
73
+ # 如果需要在本地用 token 发布(替换 YOUR_TOKEN)
74
+ npm config set //registry.npmjs.org/:_authToken=YOUR_TOKEN
75
+ ```
76
+
77
+ 4. 发布:
78
+
79
+ ```bash
80
+ npm publish --access public
81
+ ```
82
+
83
+ 在示例中测试(示例仓库已包含 `video-split-screen-example`)
84
+
85
+ 方法 A(本地 file: 引用,已在示例中设置好,方便本地开发):
86
+
87
+ ```bash
88
+ cd video-split-screen-example
89
+ npm install
90
+ npm run dev
91
+ ```
92
+
93
+ 方法 B(发布到 npm 后,切换示例依赖并安装):
94
+
95
+ 1. 在 `video-split-screen-example/package.json` 把依赖从 `file:../video-split-screen-package` 改为:
96
+
97
+ ```json
98
+ "video-split-screen": "^1.0.1"
99
+ ```
100
+
101
+ 2. 然后:
102
+
103
+ ```bash
104
+ cd video-split-screen-example
105
+ npm install
106
+ npm run dev
107
+ ```
108
+
109
+ 注意:当前打包入口同时包含命名导出与默认导出(插件 `install`)——消费者既可以使用 `app.use(VideoSplitScreen)` 全局注册,也可以按需导入 `VideoGridLayout`。如果你更偏好仅命名导出(避免 `default` 导出的歧义),我可以调整构建配置使输出仅使用命名导出。
110
+
111
+ 示例(demo 控制)
112
+
113
+ 示例项目 `video-split-screen-example/src/App.vue` 包含:
114
+ - 控制宽/高的输入框
115
+ - 全局占位文本设置
116
+ - 按钮示例:按索引设置占位符数组(演示单个/批量覆盖)
117
+
118
+ 贡献 & Issues
119
+
120
+ 欢迎在 `repository` 中提交 issue / PR,或把你希望支持的更多布局和行为告诉我。
121
+
122
+
123
+
@@ -0,0 +1,10 @@
1
+ export * from './types';
2
+ import './styles/default.css';
3
+ export * from './layoutConfig';
4
+ export { default as VideoGridLayout } from './components/VideoGridLayout.vue';
5
+ export { default as VideoLayoutIcon } from './components/VideoLayoutIcon.vue';
6
+ import type { App } from 'vue';
7
+ declare const _default: {
8
+ install(app: App): void;
9
+ };
10
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),p={1:{type:"1",label:"1分屏",count:1,cols:1,rows:1},2:{type:"2",label:"2分屏",count:2,cols:2,rows:1},3:{type:"3",label:"3分屏",count:3,cols:2,rows:2},4:{type:"4",label:"4分屏",count:4,cols:2,rows:2},6:{type:"6",label:"6分屏",count:6,cols:3,rows:2},7:{type:"7",label:"7分屏",count:7,cols:4,rows:4},8:{type:"8",label:"8分屏",count:8,cols:4,rows:4},9:{type:"9",label:"9分屏",count:9,cols:3,rows:3},10:{type:"10",label:"10分屏",count:10,cols:6,rows:4},13:{type:"13",label:"13分屏",count:13,cols:4,rows:4},16:{type:"16",label:"16分屏",count:16,cols:4,rows:4}},x={};function V(c){if(x[c])return x[c];const o={1:[{col:1,colSpan:1,row:1,rowSpan:1}],2:[{col:1,colSpan:1,row:1,rowSpan:1},{col:2,colSpan:1,row:1,rowSpan:1}],3:[{col:1,colSpan:1,row:1,rowSpan:2,isMain:!0},{col:2,colSpan:1,row:1,rowSpan:1},{col:2,colSpan:1,row:2,rowSpan:1}],4:[{col:1,colSpan:1,row:1,rowSpan:1},{col:2,colSpan:1,row:1,rowSpan:1},{col:1,colSpan:1,row:2,rowSpan:1},{col:2,colSpan:1,row:2,rowSpan:1}],6:[{col:1,colSpan:1,row:1,rowSpan:1},{col:2,colSpan:1,row:1,rowSpan:1},{col:3,colSpan:1,row:1,rowSpan:1},{col:1,colSpan:1,row:2,rowSpan:1},{col:2,colSpan:1,row:2,rowSpan:1},{col:3,colSpan:1,row:2,rowSpan:1}],7:[{col:1,colSpan:2,row:1,rowSpan:2},{col:3,colSpan:2,row:1,rowSpan:2},{col:1,colSpan:2,row:3,rowSpan:2},{col:3,colSpan:1,row:3,rowSpan:1},{col:4,colSpan:1,row:3,rowSpan:1},{col:3,colSpan:1,row:4,rowSpan:1},{col:4,colSpan:1,row:4,rowSpan:1}],8:[{col:1,colSpan:3,row:1,rowSpan:3,isMain:!0},{col:4,colSpan:1,row:1,rowSpan:1},{col:4,colSpan:1,row:2,rowSpan:1},{col:4,colSpan:1,row:3,rowSpan:1},{col:1,colSpan:1,row:4,rowSpan:1},{col:2,colSpan:1,row:4,rowSpan:1},{col:3,colSpan:1,row:4,rowSpan:1},{col:4,colSpan:1,row:4,rowSpan:1}],9:[{col:1,colSpan:1,row:1,rowSpan:1},{col:2,colSpan:1,row:1,rowSpan:1},{col:3,colSpan:1,row:1,rowSpan:1},{col:1,colSpan:1,row:2,rowSpan:1},{col:2,colSpan:1,row:2,rowSpan:1},{col:3,colSpan:1,row:2,rowSpan:1},{col:1,colSpan:1,row:3,rowSpan:1},{col:2,colSpan:1,row:3,rowSpan:1},{col:3,colSpan:1,row:3,rowSpan:1}],10:[{col:1,colSpan:5,row:1,rowSpan:3,isMain:!0},{col:6,colSpan:1,row:1,rowSpan:1},{col:6,colSpan:1,row:2,rowSpan:1},{col:6,colSpan:1,row:3,rowSpan:1},{col:1,colSpan:1,row:4,rowSpan:1},{col:2,colSpan:1,row:4,rowSpan:1},{col:3,colSpan:1,row:4,rowSpan:1},{col:4,colSpan:1,row:4,rowSpan:1},{col:5,colSpan:1,row:4,rowSpan:1},{col:6,colSpan:1,row:4,rowSpan:1}],13:[{col:1,colSpan:2,row:1,rowSpan:2,isMain:!0},{col:3,colSpan:1,row:1,rowSpan:1},{col:4,colSpan:1,row:1,rowSpan:1},{col:3,colSpan:1,row:2,rowSpan:1},{col:4,colSpan:1,row:2,rowSpan:1},{col:1,colSpan:1,row:3,rowSpan:1},{col:2,colSpan:1,row:3,rowSpan:1},{col:3,colSpan:1,row:3,rowSpan:1},{col:4,colSpan:1,row:3,rowSpan:1},{col:1,colSpan:1,row:4,rowSpan:1},{col:2,colSpan:1,row:4,rowSpan:1},{col:3,colSpan:1,row:4,rowSpan:1},{col:4,colSpan:1,row:4,rowSpan:1}],16:[{col:1,colSpan:1,row:1,rowSpan:1},{col:2,colSpan:1,row:1,rowSpan:1},{col:3,colSpan:1,row:1,rowSpan:1},{col:4,colSpan:1,row:1,rowSpan:1},{col:1,colSpan:1,row:2,rowSpan:1},{col:2,colSpan:1,row:2,rowSpan:1},{col:3,colSpan:1,row:2,rowSpan:1},{col:4,colSpan:1,row:2,rowSpan:1},{col:1,colSpan:1,row:3,rowSpan:1},{col:2,colSpan:1,row:3,rowSpan:1},{col:3,colSpan:1,row:3,rowSpan:1},{col:4,colSpan:1,row:3,rowSpan:1},{col:1,colSpan:1,row:4,rowSpan:1},{col:2,colSpan:1,row:4,rowSpan:1},{col:3,colSpan:1,row:4,rowSpan:1},{col:4,colSpan:1,row:4,rowSpan:1}]}[c]||[];return o.length>0&&(x[c]=o),o}function L(){return Object.keys(p)}const Y={class:"layout-icon"},j={key:0,viewBox:"0 0 48 48",fill:"none"},H={key:1,viewBox:"0 0 48 48",fill:"none"},W={key:2,viewBox:"0 0 48 48",fill:"none"},q={key:3,viewBox:"0 0 48 48",fill:"none"},J={key:4,viewBox:"0 0 48 48",fill:"none"},K={key:5,viewBox:"0 0 48 48",fill:"none"},Q={key:6,viewBox:"0 0 48 48",fill:"none"},X={key:7,viewBox:"0 0 48 48",fill:"none"},Z={key:8,viewBox:"0 0 54 48",fill:"none"},ee={key:9,viewBox:"0 0 48 48",fill:"none"},te={key:10,viewBox:"0 0 48 48",fill:"none"},oe=e.defineComponent({__name:"VideoLayoutIcon",props:{type:{}},setup(c){return(w,o)=>(e.openBlock(),e.createElementBlock("div",Y,[c.type==="1"?(e.openBlock(),e.createElementBlock("svg",j,[...o[0]||(o[0]=[e.createElementVNode("rect",{x:"4",y:"4",width:"40",height:"40",stroke:"currentColor","stroke-width":"2"},null,-1)])])):c.type==="2"?(e.openBlock(),e.createElementBlock("svg",H,[...o[1]||(o[1]=[e.createElementVNode("rect",{x:"4",y:"4",width:"19",height:"40",stroke:"currentColor","stroke-width":"1.5"},null,-1),e.createElementVNode("rect",{x:"25",y:"4",width:"19",height:"40",stroke:"currentColor","stroke-width":"1.5"},null,-1)])])):c.type==="3"?(e.openBlock(),e.createElementBlock("svg",W,[...o[2]||(o[2]=[e.createElementVNode("rect",{x:"4",y:"4",width:"20",height:"40",stroke:"currentColor","stroke-width":"2"},null,-1),e.createElementVNode("rect",{x:"26",y:"4",width:"18",height:"19",stroke:"currentColor","stroke-width":"1.5"},null,-1),e.createElementVNode("rect",{x:"26",y:"25",width:"18",height:"19",stroke:"currentColor","stroke-width":"1.5"},null,-1)])])):c.type==="4"?(e.openBlock(),e.createElementBlock("svg",q,[...o[3]||(o[3]=[e.createElementVNode("rect",{x:"4",y:"4",width:"19",height:"19",stroke:"currentColor","stroke-width":"1.5"},null,-1),e.createElementVNode("rect",{x:"25",y:"4",width:"19",height:"19",stroke:"currentColor","stroke-width":"1.5"},null,-1),e.createElementVNode("rect",{x:"4",y:"25",width:"19",height:"19",stroke:"currentColor","stroke-width":"1.5"},null,-1),e.createElementVNode("rect",{x:"25",y:"25",width:"19",height:"19",stroke:"currentColor","stroke-width":"1.5"},null,-1)])])):c.type==="6"?(e.openBlock(),e.createElementBlock("svg",J,[...o[4]||(o[4]=[e.createStaticVNode('<rect x="3" y="4" width="13" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="4" width="12" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="4" width="13" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="3" y="24" width="13" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="24" width="12" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="24" width="13" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect>',6)])])):c.type==="7"?(e.openBlock(),e.createElementBlock("svg",K,[...o[5]||(o[5]=[e.createStaticVNode('<rect x="4" y="4" width="19" height="19" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="25" y="4" width="19" height="19" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="4" y="25" width="19" height="19" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="25" y="25" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="35" y="25" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="25" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="35" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>',7)])])):c.type==="8"?(e.openBlock(),e.createElementBlock("svg",Q,[...o[6]||(o[6]=[e.createStaticVNode('<rect x="4" y="4" width="28" height="29" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="34" y="4" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="14.5" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="24.5" width="10" height="8.5" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="14" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="24" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="35" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>',8)])])):c.type==="9"?(e.openBlock(),e.createElementBlock("svg",X,[...o[7]||(o[7]=[e.createStaticVNode('<rect x="4" y="4" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="4" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="4" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="4" y="18" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="18" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="18" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="4" y="32" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="32" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="32" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect>',9)])])):c.type==="10"?(e.openBlock(),e.createElementBlock("svg",Z,[...o[8]||(o[8]=[e.createStaticVNode('<rect x="3" y="4" width="36" height="29" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="41" y="4" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="41" y="14.5" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="41" y="24.5" width="10" height="8.5" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="3" y="35" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="11" y="35" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="19" y="35" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="27" y="35" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="35" y="35" width="6" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="42" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>',10)])])):c.type==="13"?(e.openBlock(),e.createElementBlock("svg",ee,[...o[9]||(o[9]=[e.createStaticVNode('<rect x="4" y="4" width="18" height="18" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="24" y="4" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="4" width="10" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="24" y="14" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="14" width="10" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="24" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="14" y="24" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="24" y="24" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="24" width="10" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="34" width="8" height="10" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="14" y="34" width="8" height="10" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="24" y="34" width="8" height="10" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="34" width="10" height="10" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>',13)])])):c.type==="16"?(e.openBlock(),e.createElementBlock("svg",te,[...o[10]||(o[10]=[e.createStaticVNode('<rect x="4" y="4" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="15" y="4" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="26" y="4" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="37" y="4" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="15" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="15" y="15" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="26" y="15" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="37" y="15" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="26" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="15" y="26" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="26" y="26" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="37" y="26" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="37" width="9" height="7" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="15" y="37" width="9" height="7" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="26" y="37" width="9" height="7" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="37" y="37" width="7" height="7" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>',16)])])):e.createCommentVNode("",!0)]))}}),N=(c,w)=>{const o=c.__vccOpts||c;for(const[v,d]of w)o[v]=d;return o},B=N(oe,[["__scopeId","data-v-31e0404d"]]),re={key:0,class:"layout-toolbar",role:"toolbar","aria-label":"布局切换工具栏"},ae={class:"layout-buttons"},le=["onClick","title","aria-label","aria-pressed"],ce={class:"layout-label"},ne={class:"video-grid-container",role:"region","aria-label":"视频网格"},ie=["aria-label","onDragstart","onDragenter","onDragleave","onDrop"],de={key:0,class:"video-placeholder"},se={class:"placeholder-number"},he={key:1,style:{width:"100%",height:"100%"}},we=.5,ue="grabbing",pe="0.8",ke=e.defineComponent({__name:"VideoGridLayout",props:{videos:{},layout:{default:"1"},availableLayouts:{},showToolbar:{type:Boolean,default:!0},width:{},height:{},placeholderText:{},placeholders:{}},emits:["layoutChange","videosChange"],setup(c,{emit:w}){const o=c,v=w,d=e.ref(o.layout);e.watch(()=>o.layout,t=>{d.value=t});const I=e.computed(()=>o.availableLayouts&&o.availableLayouts.length>0?o.availableLayouts:L()),i=e.shallowRef([...o.videos]);e.watch(()=>o.videos,t=>{if(!Array.isArray(t)){console.warn("[VideoGridLayout] Invalid videos prop, expected array");return}(i.value.length!==t.length||i.value.some((r,l)=>{var a;return r.id!==((a=t[l])==null?void 0:a.id)}))&&(i.value=[...t])},{flush:"post"});let C=!1;e.watch(i,t=>{!C&&Array.isArray(t)&&v("videosChange",t)});const b=e.computed(()=>{const t=p[d.value];return t||(console.warn(`[VideoGridLayout] Invalid layout type: ${d.value}, fallback to '4'`),p[4])}),m=e.computed(()=>V(d.value)),$=e.computed(()=>{var t;return((t=b.value)==null?void 0:t.count)||4}),k=e.computed(()=>i.value.slice(0,$.value)),E=e.computed(()=>{const t=m.value.map((r,l)=>({p:r,idx:l}));return t.sort((r,l)=>r.p.row===l.p.row?(r.p.col||0)-(l.p.col||0):(r.p.row||0)-(l.p.row||0)),t.map(r=>r.idx)}),s=e.ref(-1),y=e.ref(-1),S=e.shallowRef(null),_=e.computed(()=>{const t=b.value;return{display:"grid",gridTemplateColumns:(t==null?void 0:t.colTemplate)||`repeat(${(t==null?void 0:t.cols)||2}, 1fr)`,gridTemplateRows:(t==null?void 0:t.rowTemplate)||`repeat(${(t==null?void 0:t.rows)||2}, 1fr)`,gap:"4px",width:o.width||"100%",height:o.height||"100%"}}),A=e.computed(()=>({width:o.width||"100%",height:o.height||"100%"}));function G(t){const r=t,l=E.value[r];if(k.value[l])return"";if(Array.isArray(o.placeholders)&&o.placeholders[l]!==void 0)return String(o.placeholders[l]);if(typeof o.placeholderText=="function")try{return o.placeholderText(r)}catch{return String(r+1)}return o.placeholderText?String(o.placeholderText):String(r+1)}function T(t){const r=m.value[t];return!r||typeof r.col!="number"||typeof r.row!="number"?{}:{gridColumn:`${r.col} / span ${r.colSpan}`,gridRow:`${r.row} / span ${r.rowSpan}`}}function O(t){const r=m.value[t];return(r==null?void 0:r.isMain)||!1}function M(t){d.value=t,v("layoutChange",d.value)}function g(){if(S.value&&document.body.contains(S.value)){try{document.body.removeChild(S.value)}catch(t){console.warn("[VideoGridLayout] Failed to cleanup drag image:",t)}S.value=null}}function R(t,r){if(r<0||r>=i.value.length){console.warn("[VideoGridLayout] Invalid drag index:",r);return}if(s.value=r,!t.dataTransfer)return;t.dataTransfer.effectAllowed="move";const a=t.target.closest(".video-item");if(a)try{g();const n=a.cloneNode(!0);n.style.width=`${a.offsetWidth}px`,n.style.height=`${a.offsetHeight}px`,n.style.opacity=pe,n.style.position="absolute",n.style.top="-9999px",n.style.pointerEvents="none",document.body.appendChild(n),S.value=n,t.dataTransfer.setDragImage(n,a.offsetWidth/2,a.offsetHeight/2),setTimeout(()=>{g()},100),a.style.opacity=String(we),a.style.cursor=ue}catch(n){console.error("[VideoGridLayout] Drag start error:",n),g()}}function P(t,r){t.preventDefault(),t.stopPropagation();const l=s.value;if(l===-1||l===r){s.value=-1;return}if(r<0||r>=i.value.length){console.warn("[VideoGridLayout] Invalid drop index:",r),s.value=-1;return}try{const a=i.value[l],n=i.value[r];if(a&&n){C=!0;const h=[...i.value];h[l]=n,h[r]=a,i.value=h,setTimeout(()=>{C=!1,v("videosChange",i.value)},0)}}catch(a){console.error("[VideoGridLayout] Drop error:",a)}finally{s.value=-1}}function F(t,r){t.preventDefault(),s.value!==-1&&s.value!==r&&(y.value=r)}function z(t,r){t.preventDefault();const l=t.target,a=t.relatedTarget;l.contains(a)||y.value===r&&(y.value=-1)}function U(t){const l=t.target.closest(".video-item");l&&(l.style.opacity="1",l.style.cursor="move"),g(),s.value=-1,y.value=-1}return e.onBeforeUnmount(()=>{g()}),(t,r)=>(e.openBlock(),e.createElementBlock("div",{class:"video-grid-layout",role:"application","aria-label":"视频分屏布局",style:e.normalizeStyle(A.value)},[c.showToolbar?(e.openBlock(),e.createElementBlock("div",re,[r[1]||(r[1]=e.createElementVNode("div",{class:"toolbar-title"},"分屏布局",-1)),e.createElementVNode("div",ae,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(I.value,l=>{var a,n,h;return e.openBlock(),e.createElementBlock("button",{key:l,class:e.normalizeClass(["layout-btn",{active:d.value===l}]),onClick:f=>M(l),title:((a=e.unref(p)[l])==null?void 0:a.label)||"","aria-label":`切换到${((n=e.unref(p)[l])==null?void 0:n.label)||""}布局`,"aria-pressed":d.value===l,type:"button"},[e.createVNode(B,{type:l},null,8,["type"]),e.createElementVNode("span",ce,e.toDisplayString(((h=e.unref(p)[l])==null?void 0:h.label)||""),1)],10,le)}),128))])])):e.createCommentVNode("",!0),e.createElementVNode("div",ne,[e.createElementVNode("div",{class:"video-grid",style:e.normalizeStyle(_.value)},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(m.value,(l,a)=>{var n,h,f;return e.openBlock(),e.createElementBlock("div",{key:((n=k.value[a])==null?void 0:n.id)??a,class:e.normalizeClass(["video-item",{"main-video":O(a),dragging:s.value===a,"drag-over":y.value===a&&s.value!==a}]),style:e.normalizeStyle(T(a)),draggable:!0,"aria-label":`视频 ${a+1}: ${((h=k.value[a])==null?void 0:h.title)||((f=k.value[a])==null?void 0:f.id)||""}`,role:"article",tabindex:"0",onDragstart:u=>R(u,a),onDragover:r[0]||(r[0]=e.withModifiers(()=>{},["prevent"])),onDragenter:u=>F(u,a),onDragleave:u=>z(u,a),onDrop:u=>P(u,a),onDragend:U},[e.renderSlot(t.$slots,"video",{video:k.value[a],index:a},()=>[k.value[a]?(e.openBlock(),e.createElementBlock("div",he)):(e.openBlock(),e.createElementBlock("div",de,[e.createElementVNode("div",se,e.toDisplayString(G(E.value.indexOf(a))),1)]))],!0)],46,ie)}),128))],4)])],4))}}),D=N(ke,[["__scopeId","data-v-473a71fa"]]),ve={VideoGridLayout:D,VideoLayoutIcon:B},ye={install(c){Object.entries(ve).forEach(([w,o])=>{c.component(w,o)})}};exports.LAYOUT_CONFIGS=p;exports.VideoGridLayout=D;exports.VideoLayoutIcon=B;exports.default=ye;exports.getAllLayoutTypes=L;exports.getLayoutPositions=V;
package/dist/index.mjs ADDED
@@ -0,0 +1,600 @@
1
+ import { defineComponent as N, createElementBlock as c, openBlock as i, createCommentVNode as P, createElementVNode as d, createStaticVNode as k, ref as $, watch as I, computed as p, shallowRef as T, onBeforeUnmount as et, normalizeStyle as _, Fragment as O, renderList as E, unref as A, normalizeClass as M, createVNode as rt, toDisplayString as R, withModifiers as at, renderSlot as lt } from "vue";
2
+ const g = {
3
+ 1: {
4
+ type: "1",
5
+ label: "1分屏",
6
+ count: 1,
7
+ cols: 1,
8
+ rows: 1
9
+ },
10
+ 2: {
11
+ type: "2",
12
+ label: "2分屏",
13
+ count: 2,
14
+ cols: 2,
15
+ rows: 1
16
+ },
17
+ 3: {
18
+ type: "3",
19
+ label: "3分屏",
20
+ count: 3,
21
+ cols: 2,
22
+ rows: 2
23
+ },
24
+ 4: {
25
+ type: "4",
26
+ label: "4分屏",
27
+ count: 4,
28
+ cols: 2,
29
+ rows: 2
30
+ },
31
+ 6: {
32
+ type: "6",
33
+ label: "6分屏",
34
+ count: 6,
35
+ cols: 3,
36
+ rows: 2
37
+ },
38
+ 7: {
39
+ type: "7",
40
+ label: "7分屏",
41
+ count: 7,
42
+ cols: 4,
43
+ rows: 4
44
+ },
45
+ 8: {
46
+ type: "8",
47
+ label: "8分屏",
48
+ count: 8,
49
+ cols: 4,
50
+ rows: 4
51
+ },
52
+ 9: {
53
+ type: "9",
54
+ label: "9分屏",
55
+ count: 9,
56
+ cols: 3,
57
+ rows: 3
58
+ },
59
+ 10: {
60
+ type: "10",
61
+ label: "10分屏",
62
+ count: 10,
63
+ cols: 6,
64
+ rows: 4
65
+ },
66
+ 13: {
67
+ type: "13",
68
+ label: "13分屏",
69
+ count: 13,
70
+ cols: 4,
71
+ rows: 4
72
+ },
73
+ 16: {
74
+ type: "16",
75
+ label: "16分屏",
76
+ count: 16,
77
+ cols: 4,
78
+ rows: 4
79
+ }
80
+ }, B = {};
81
+ function nt(l) {
82
+ if (B[l])
83
+ return B[l];
84
+ const o = {
85
+ 1: [
86
+ { col: 1, colSpan: 1, row: 1, rowSpan: 1 }
87
+ ],
88
+ 2: [
89
+ { col: 1, colSpan: 1, row: 1, rowSpan: 1 },
90
+ { col: 2, colSpan: 1, row: 1, rowSpan: 1 }
91
+ ],
92
+ 3: [
93
+ { col: 1, colSpan: 1, row: 1, rowSpan: 2, isMain: !0 },
94
+ { col: 2, colSpan: 1, row: 1, rowSpan: 1 },
95
+ { col: 2, colSpan: 1, row: 2, rowSpan: 1 }
96
+ ],
97
+ 4: [
98
+ { col: 1, colSpan: 1, row: 1, rowSpan: 1 },
99
+ { col: 2, colSpan: 1, row: 1, rowSpan: 1 },
100
+ { col: 1, colSpan: 1, row: 2, rowSpan: 1 },
101
+ { col: 2, colSpan: 1, row: 2, rowSpan: 1 }
102
+ ],
103
+ 6: [
104
+ { col: 1, colSpan: 1, row: 1, rowSpan: 1 },
105
+ { col: 2, colSpan: 1, row: 1, rowSpan: 1 },
106
+ { col: 3, colSpan: 1, row: 1, rowSpan: 1 },
107
+ { col: 1, colSpan: 1, row: 2, rowSpan: 1 },
108
+ { col: 2, colSpan: 1, row: 2, rowSpan: 1 },
109
+ { col: 3, colSpan: 1, row: 2, rowSpan: 1 }
110
+ ],
111
+ 7: [
112
+ { col: 1, colSpan: 2, row: 1, rowSpan: 2 },
113
+ { col: 3, colSpan: 2, row: 1, rowSpan: 2 },
114
+ { col: 1, colSpan: 2, row: 3, rowSpan: 2 },
115
+ { col: 3, colSpan: 1, row: 3, rowSpan: 1 },
116
+ { col: 4, colSpan: 1, row: 3, rowSpan: 1 },
117
+ { col: 3, colSpan: 1, row: 4, rowSpan: 1 },
118
+ { col: 4, colSpan: 1, row: 4, rowSpan: 1 }
119
+ ],
120
+ 8: [
121
+ { col: 1, colSpan: 3, row: 1, rowSpan: 3, isMain: !0 },
122
+ { col: 4, colSpan: 1, row: 1, rowSpan: 1 },
123
+ { col: 4, colSpan: 1, row: 2, rowSpan: 1 },
124
+ { col: 4, colSpan: 1, row: 3, rowSpan: 1 },
125
+ { col: 1, colSpan: 1, row: 4, rowSpan: 1 },
126
+ { col: 2, colSpan: 1, row: 4, rowSpan: 1 },
127
+ { col: 3, colSpan: 1, row: 4, rowSpan: 1 },
128
+ { col: 4, colSpan: 1, row: 4, rowSpan: 1 }
129
+ ],
130
+ 9: [
131
+ { col: 1, colSpan: 1, row: 1, rowSpan: 1 },
132
+ { col: 2, colSpan: 1, row: 1, rowSpan: 1 },
133
+ { col: 3, colSpan: 1, row: 1, rowSpan: 1 },
134
+ { col: 1, colSpan: 1, row: 2, rowSpan: 1 },
135
+ { col: 2, colSpan: 1, row: 2, rowSpan: 1 },
136
+ { col: 3, colSpan: 1, row: 2, rowSpan: 1 },
137
+ { col: 1, colSpan: 1, row: 3, rowSpan: 1 },
138
+ { col: 2, colSpan: 1, row: 3, rowSpan: 1 },
139
+ { col: 3, colSpan: 1, row: 3, rowSpan: 1 }
140
+ ],
141
+ 10: [
142
+ { col: 1, colSpan: 5, row: 1, rowSpan: 3, isMain: !0 },
143
+ { col: 6, colSpan: 1, row: 1, rowSpan: 1 },
144
+ { col: 6, colSpan: 1, row: 2, rowSpan: 1 },
145
+ { col: 6, colSpan: 1, row: 3, rowSpan: 1 },
146
+ { col: 1, colSpan: 1, row: 4, rowSpan: 1 },
147
+ { col: 2, colSpan: 1, row: 4, rowSpan: 1 },
148
+ { col: 3, colSpan: 1, row: 4, rowSpan: 1 },
149
+ { col: 4, colSpan: 1, row: 4, rowSpan: 1 },
150
+ { col: 5, colSpan: 1, row: 4, rowSpan: 1 },
151
+ { col: 6, colSpan: 1, row: 4, rowSpan: 1 }
152
+ ],
153
+ 13: [
154
+ { col: 1, colSpan: 2, row: 1, rowSpan: 2, isMain: !0 },
155
+ { col: 3, colSpan: 1, row: 1, rowSpan: 1 },
156
+ { col: 4, colSpan: 1, row: 1, rowSpan: 1 },
157
+ { col: 3, colSpan: 1, row: 2, rowSpan: 1 },
158
+ { col: 4, colSpan: 1, row: 2, rowSpan: 1 },
159
+ { col: 1, colSpan: 1, row: 3, rowSpan: 1 },
160
+ { col: 2, colSpan: 1, row: 3, rowSpan: 1 },
161
+ { col: 3, colSpan: 1, row: 3, rowSpan: 1 },
162
+ { col: 4, colSpan: 1, row: 3, rowSpan: 1 },
163
+ { col: 1, colSpan: 1, row: 4, rowSpan: 1 },
164
+ { col: 2, colSpan: 1, row: 4, rowSpan: 1 },
165
+ { col: 3, colSpan: 1, row: 4, rowSpan: 1 },
166
+ { col: 4, colSpan: 1, row: 4, rowSpan: 1 }
167
+ ],
168
+ 16: [
169
+ { col: 1, colSpan: 1, row: 1, rowSpan: 1 },
170
+ { col: 2, colSpan: 1, row: 1, rowSpan: 1 },
171
+ { col: 3, colSpan: 1, row: 1, rowSpan: 1 },
172
+ { col: 4, colSpan: 1, row: 1, rowSpan: 1 },
173
+ { col: 1, colSpan: 1, row: 2, rowSpan: 1 },
174
+ { col: 2, colSpan: 1, row: 2, rowSpan: 1 },
175
+ { col: 3, colSpan: 1, row: 2, rowSpan: 1 },
176
+ { col: 4, colSpan: 1, row: 2, rowSpan: 1 },
177
+ { col: 1, colSpan: 1, row: 3, rowSpan: 1 },
178
+ { col: 2, colSpan: 1, row: 3, rowSpan: 1 },
179
+ { col: 3, colSpan: 1, row: 3, rowSpan: 1 },
180
+ { col: 4, colSpan: 1, row: 3, rowSpan: 1 },
181
+ { col: 1, colSpan: 1, row: 4, rowSpan: 1 },
182
+ { col: 2, colSpan: 1, row: 4, rowSpan: 1 },
183
+ { col: 3, colSpan: 1, row: 4, rowSpan: 1 },
184
+ { col: 4, colSpan: 1, row: 4, rowSpan: 1 }
185
+ ]
186
+ }[l] || [];
187
+ return o.length > 0 && (B[l] = o), o;
188
+ }
189
+ function ct() {
190
+ return Object.keys(g);
191
+ }
192
+ const it = { class: "layout-icon" }, dt = {
193
+ key: 0,
194
+ viewBox: "0 0 48 48",
195
+ fill: "none"
196
+ }, st = {
197
+ key: 1,
198
+ viewBox: "0 0 48 48",
199
+ fill: "none"
200
+ }, ht = {
201
+ key: 2,
202
+ viewBox: "0 0 48 48",
203
+ fill: "none"
204
+ }, wt = {
205
+ key: 3,
206
+ viewBox: "0 0 48 48",
207
+ fill: "none"
208
+ }, ut = {
209
+ key: 4,
210
+ viewBox: "0 0 48 48",
211
+ fill: "none"
212
+ }, pt = {
213
+ key: 5,
214
+ viewBox: "0 0 48 48",
215
+ fill: "none"
216
+ }, vt = {
217
+ key: 6,
218
+ viewBox: "0 0 48 48",
219
+ fill: "none"
220
+ }, yt = {
221
+ key: 7,
222
+ viewBox: "0 0 48 48",
223
+ fill: "none"
224
+ }, kt = {
225
+ key: 8,
226
+ viewBox: "0 0 54 48",
227
+ fill: "none"
228
+ }, St = {
229
+ key: 9,
230
+ viewBox: "0 0 48 48",
231
+ fill: "none"
232
+ }, gt = {
233
+ key: 10,
234
+ viewBox: "0 0 48 48",
235
+ fill: "none"
236
+ }, Ct = /* @__PURE__ */ N({
237
+ __name: "VideoLayoutIcon",
238
+ props: {
239
+ type: {}
240
+ },
241
+ setup(l) {
242
+ return (v, o) => (i(), c("div", it, [
243
+ l.type === "1" ? (i(), c("svg", dt, [...o[0] || (o[0] = [
244
+ d("rect", {
245
+ x: "4",
246
+ y: "4",
247
+ width: "40",
248
+ height: "40",
249
+ stroke: "currentColor",
250
+ "stroke-width": "2"
251
+ }, null, -1)
252
+ ])])) : l.type === "2" ? (i(), c("svg", st, [...o[1] || (o[1] = [
253
+ d("rect", {
254
+ x: "4",
255
+ y: "4",
256
+ width: "19",
257
+ height: "40",
258
+ stroke: "currentColor",
259
+ "stroke-width": "1.5"
260
+ }, null, -1),
261
+ d("rect", {
262
+ x: "25",
263
+ y: "4",
264
+ width: "19",
265
+ height: "40",
266
+ stroke: "currentColor",
267
+ "stroke-width": "1.5"
268
+ }, null, -1)
269
+ ])])) : l.type === "3" ? (i(), c("svg", ht, [...o[2] || (o[2] = [
270
+ d("rect", {
271
+ x: "4",
272
+ y: "4",
273
+ width: "20",
274
+ height: "40",
275
+ stroke: "currentColor",
276
+ "stroke-width": "2"
277
+ }, null, -1),
278
+ d("rect", {
279
+ x: "26",
280
+ y: "4",
281
+ width: "18",
282
+ height: "19",
283
+ stroke: "currentColor",
284
+ "stroke-width": "1.5"
285
+ }, null, -1),
286
+ d("rect", {
287
+ x: "26",
288
+ y: "25",
289
+ width: "18",
290
+ height: "19",
291
+ stroke: "currentColor",
292
+ "stroke-width": "1.5"
293
+ }, null, -1)
294
+ ])])) : l.type === "4" ? (i(), c("svg", wt, [...o[3] || (o[3] = [
295
+ d("rect", {
296
+ x: "4",
297
+ y: "4",
298
+ width: "19",
299
+ height: "19",
300
+ stroke: "currentColor",
301
+ "stroke-width": "1.5"
302
+ }, null, -1),
303
+ d("rect", {
304
+ x: "25",
305
+ y: "4",
306
+ width: "19",
307
+ height: "19",
308
+ stroke: "currentColor",
309
+ "stroke-width": "1.5"
310
+ }, null, -1),
311
+ d("rect", {
312
+ x: "4",
313
+ y: "25",
314
+ width: "19",
315
+ height: "19",
316
+ stroke: "currentColor",
317
+ "stroke-width": "1.5"
318
+ }, null, -1),
319
+ d("rect", {
320
+ x: "25",
321
+ y: "25",
322
+ width: "19",
323
+ height: "19",
324
+ stroke: "currentColor",
325
+ "stroke-width": "1.5"
326
+ }, null, -1)
327
+ ])])) : l.type === "6" ? (i(), c("svg", ut, [...o[4] || (o[4] = [
328
+ k('<rect x="3" y="4" width="13" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="4" width="12" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="4" width="13" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="3" y="24" width="13" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="24" width="12" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="24" width="13" height="18" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect>', 6)
329
+ ])])) : l.type === "7" ? (i(), c("svg", pt, [...o[5] || (o[5] = [
330
+ k('<rect x="4" y="4" width="19" height="19" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="25" y="4" width="19" height="19" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="4" y="25" width="19" height="19" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="25" y="25" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="35" y="25" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="25" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="35" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>', 7)
331
+ ])])) : l.type === "8" ? (i(), c("svg", vt, [...o[6] || (o[6] = [
332
+ k('<rect x="4" y="4" width="28" height="29" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="34" y="4" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="14.5" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="24.5" width="10" height="8.5" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="14" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="24" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="35" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>', 8)
333
+ ])])) : l.type === "9" ? (i(), c("svg", yt, [...o[7] || (o[7] = [
334
+ k('<rect x="4" y="4" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="4" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="4" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="4" y="18" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="18" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="18" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="4" y="32" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="18" y="32" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect><rect x="32" y="32" width="12" height="12" stroke="currentColor" stroke-width="1.5" data-v-31e0404d></rect>', 9)
335
+ ])])) : l.type === "10" ? (i(), c("svg", kt, [...o[8] || (o[8] = [
336
+ k('<rect x="3" y="4" width="36" height="29" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="41" y="4" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="41" y="14.5" width="10" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="41" y="24.5" width="10" height="8.5" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="3" y="35" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="11" y="35" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="19" y="35" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="27" y="35" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="35" y="35" width="6" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="42" y="35" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>', 10)
337
+ ])])) : l.type === "13" ? (i(), c("svg", St, [...o[9] || (o[9] = [
338
+ k('<rect x="4" y="4" width="18" height="18" stroke="currentColor" stroke-width="2" data-v-31e0404d></rect><rect x="24" y="4" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="4" width="10" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="24" y="14" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="14" width="10" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="24" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="14" y="24" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="24" y="24" width="8" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="24" width="10" height="8" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="34" width="8" height="10" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="14" y="34" width="8" height="10" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="24" y="34" width="8" height="10" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="34" y="34" width="10" height="10" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>', 13)
339
+ ])])) : l.type === "16" ? (i(), c("svg", gt, [...o[10] || (o[10] = [
340
+ k('<rect x="4" y="4" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="15" y="4" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="26" y="4" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="37" y="4" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="15" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="15" y="15" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="26" y="15" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="37" y="15" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="26" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="15" y="26" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="26" y="26" width="9" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="37" y="26" width="7" height="9" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="4" y="37" width="9" height="7" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="15" y="37" width="9" height="7" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="26" y="37" width="9" height="7" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect><rect x="37" y="37" width="7" height="7" stroke="currentColor" stroke-width="1.2" data-v-31e0404d></rect>', 16)
341
+ ])])) : P("", !0)
342
+ ]));
343
+ }
344
+ }), F = (l, v) => {
345
+ const o = l.__vccOpts || l;
346
+ for (const [C, h] of v)
347
+ o[C] = h;
348
+ return o;
349
+ }, U = /* @__PURE__ */ F(Ct, [["__scopeId", "data-v-31e0404d"]]), xt = {
350
+ key: 0,
351
+ class: "layout-toolbar",
352
+ role: "toolbar",
353
+ "aria-label": "布局切换工具栏"
354
+ }, ft = { class: "layout-buttons" }, mt = ["onClick", "title", "aria-label", "aria-pressed"], bt = { class: "layout-label" }, Dt = {
355
+ class: "video-grid-container",
356
+ role: "region",
357
+ "aria-label": "视频网格"
358
+ }, Lt = ["aria-label", "onDragstart", "onDragenter", "onDragleave", "onDrop"], $t = {
359
+ key: 0,
360
+ class: "video-placeholder"
361
+ }, It = { class: "placeholder-number" }, _t = {
362
+ key: 1,
363
+ style: { width: "100%", height: "100%" }
364
+ }, At = 0.5, Bt = "grabbing", Vt = "0.8", Gt = /* @__PURE__ */ N({
365
+ __name: "VideoGridLayout",
366
+ props: {
367
+ videos: {},
368
+ layout: { default: "1" },
369
+ availableLayouts: {},
370
+ showToolbar: { type: Boolean, default: !0 },
371
+ width: {},
372
+ height: {},
373
+ placeholderText: {},
374
+ placeholders: {}
375
+ },
376
+ emits: ["layoutChange", "videosChange"],
377
+ setup(l, { emit: v }) {
378
+ const o = l, C = v, h = $(o.layout);
379
+ I(() => o.layout, (t) => {
380
+ h.value = t;
381
+ });
382
+ const Y = p(() => o.availableLayouts && o.availableLayouts.length > 0 ? o.availableLayouts : ct()), s = T([...o.videos]);
383
+ I(() => o.videos, (t) => {
384
+ if (!Array.isArray(t)) {
385
+ console.warn("[VideoGridLayout] Invalid videos prop, expected array");
386
+ return;
387
+ }
388
+ (s.value.length !== t.length || s.value.some((e, a) => {
389
+ var r;
390
+ return e.id !== ((r = t[a]) == null ? void 0 : r.id);
391
+ })) && (s.value = [...t]);
392
+ }, { flush: "post" });
393
+ let D = !1;
394
+ I(s, (t) => {
395
+ !D && Array.isArray(t) && C("videosChange", t);
396
+ });
397
+ const V = p(() => {
398
+ const t = g[h.value];
399
+ return t || (console.warn(`[VideoGridLayout] Invalid layout type: ${h.value}, fallback to '4'`), g[4]);
400
+ }), b = p(() => nt(h.value)), j = p(() => {
401
+ var t;
402
+ return ((t = V.value) == null ? void 0 : t.count) || 4;
403
+ }), S = p(() => s.value.slice(0, j.value)), G = p(() => {
404
+ const t = b.value.map((e, a) => ({ p: e, idx: a }));
405
+ return t.sort((e, a) => e.p.row === a.p.row ? (e.p.col || 0) - (a.p.col || 0) : (e.p.row || 0) - (a.p.row || 0)), t.map((e) => e.idx);
406
+ }), w = $(-1), x = $(-1), f = T(null), z = p(() => {
407
+ const t = V.value;
408
+ return {
409
+ display: "grid",
410
+ gridTemplateColumns: (t == null ? void 0 : t.colTemplate) || `repeat(${(t == null ? void 0 : t.cols) || 2}, 1fr)`,
411
+ gridTemplateRows: (t == null ? void 0 : t.rowTemplate) || `repeat(${(t == null ? void 0 : t.rows) || 2}, 1fr)`,
412
+ gap: "4px",
413
+ width: o.width || "100%",
414
+ height: o.height || "100%"
415
+ };
416
+ }), H = p(() => ({
417
+ width: o.width || "100%",
418
+ height: o.height || "100%"
419
+ }));
420
+ function W(t) {
421
+ const e = t, a = G.value[e];
422
+ if (S.value[a]) return "";
423
+ if (Array.isArray(o.placeholders) && o.placeholders[a] !== void 0)
424
+ return String(o.placeholders[a]);
425
+ if (typeof o.placeholderText == "function")
426
+ try {
427
+ return o.placeholderText(e);
428
+ } catch {
429
+ return String(e + 1);
430
+ }
431
+ return o.placeholderText ? String(o.placeholderText) : String(e + 1);
432
+ }
433
+ function q(t) {
434
+ const e = b.value[t];
435
+ return !e || typeof e.col != "number" || typeof e.row != "number" ? {} : {
436
+ gridColumn: `${e.col} / span ${e.colSpan}`,
437
+ gridRow: `${e.row} / span ${e.rowSpan}`
438
+ };
439
+ }
440
+ function J(t) {
441
+ const e = b.value[t];
442
+ return (e == null ? void 0 : e.isMain) || !1;
443
+ }
444
+ function K(t) {
445
+ h.value = t, C("layoutChange", h.value);
446
+ }
447
+ function m() {
448
+ if (f.value && document.body.contains(f.value)) {
449
+ try {
450
+ document.body.removeChild(f.value);
451
+ } catch (t) {
452
+ console.warn("[VideoGridLayout] Failed to cleanup drag image:", t);
453
+ }
454
+ f.value = null;
455
+ }
456
+ }
457
+ function Q(t, e) {
458
+ if (e < 0 || e >= s.value.length) {
459
+ console.warn("[VideoGridLayout] Invalid drag index:", e);
460
+ return;
461
+ }
462
+ if (w.value = e, !t.dataTransfer) return;
463
+ t.dataTransfer.effectAllowed = "move";
464
+ const r = t.target.closest(".video-item");
465
+ if (r)
466
+ try {
467
+ m();
468
+ const n = r.cloneNode(!0);
469
+ n.style.width = `${r.offsetWidth}px`, n.style.height = `${r.offsetHeight}px`, n.style.opacity = Vt, n.style.position = "absolute", n.style.top = "-9999px", n.style.pointerEvents = "none", document.body.appendChild(n), f.value = n, t.dataTransfer.setDragImage(n, r.offsetWidth / 2, r.offsetHeight / 2), setTimeout(() => {
470
+ m();
471
+ }, 100), r.style.opacity = String(At), r.style.cursor = Bt;
472
+ } catch (n) {
473
+ console.error("[VideoGridLayout] Drag start error:", n), m();
474
+ }
475
+ }
476
+ function X(t, e) {
477
+ t.preventDefault(), t.stopPropagation();
478
+ const a = w.value;
479
+ if (a === -1 || a === e) {
480
+ w.value = -1;
481
+ return;
482
+ }
483
+ if (e < 0 || e >= s.value.length) {
484
+ console.warn("[VideoGridLayout] Invalid drop index:", e), w.value = -1;
485
+ return;
486
+ }
487
+ try {
488
+ const r = s.value[a], n = s.value[e];
489
+ if (r && n) {
490
+ D = !0;
491
+ const u = [...s.value];
492
+ u[a] = n, u[e] = r, s.value = u, setTimeout(() => {
493
+ D = !1, C("videosChange", s.value);
494
+ }, 0);
495
+ }
496
+ } catch (r) {
497
+ console.error("[VideoGridLayout] Drop error:", r);
498
+ } finally {
499
+ w.value = -1;
500
+ }
501
+ }
502
+ function Z(t, e) {
503
+ t.preventDefault(), w.value !== -1 && w.value !== e && (x.value = e);
504
+ }
505
+ function tt(t, e) {
506
+ t.preventDefault();
507
+ const a = t.target, r = t.relatedTarget;
508
+ a.contains(r) || x.value === e && (x.value = -1);
509
+ }
510
+ function ot(t) {
511
+ const a = t.target.closest(".video-item");
512
+ a && (a.style.opacity = "1", a.style.cursor = "move"), m(), w.value = -1, x.value = -1;
513
+ }
514
+ return et(() => {
515
+ m();
516
+ }), (t, e) => (i(), c("div", {
517
+ class: "video-grid-layout",
518
+ role: "application",
519
+ "aria-label": "视频分屏布局",
520
+ style: _(H.value)
521
+ }, [
522
+ l.showToolbar ? (i(), c("div", xt, [
523
+ e[1] || (e[1] = d("div", { class: "toolbar-title" }, "分屏布局", -1)),
524
+ d("div", ft, [
525
+ (i(!0), c(O, null, E(Y.value, (a) => {
526
+ var r, n, u;
527
+ return i(), c("button", {
528
+ key: a,
529
+ class: M(["layout-btn", { active: h.value === a }]),
530
+ onClick: (L) => K(a),
531
+ title: ((r = A(g)[a]) == null ? void 0 : r.label) || "",
532
+ "aria-label": `切换到${((n = A(g)[a]) == null ? void 0 : n.label) || ""}布局`,
533
+ "aria-pressed": h.value === a,
534
+ type: "button"
535
+ }, [
536
+ rt(U, { type: a }, null, 8, ["type"]),
537
+ d("span", bt, R(((u = A(g)[a]) == null ? void 0 : u.label) || ""), 1)
538
+ ], 10, mt);
539
+ }), 128))
540
+ ])
541
+ ])) : P("", !0),
542
+ d("div", Dt, [
543
+ d("div", {
544
+ class: "video-grid",
545
+ style: _(z.value)
546
+ }, [
547
+ (i(!0), c(O, null, E(b.value, (a, r) => {
548
+ var n, u, L;
549
+ return i(), c("div", {
550
+ key: ((n = S.value[r]) == null ? void 0 : n.id) ?? r,
551
+ class: M(["video-item", {
552
+ "main-video": J(r),
553
+ dragging: w.value === r,
554
+ "drag-over": x.value === r && w.value !== r
555
+ }]),
556
+ style: _(q(r)),
557
+ draggable: !0,
558
+ "aria-label": `视频 ${r + 1}: ${((u = S.value[r]) == null ? void 0 : u.title) || ((L = S.value[r]) == null ? void 0 : L.id) || ""}`,
559
+ role: "article",
560
+ tabindex: "0",
561
+ onDragstart: (y) => Q(y, r),
562
+ onDragover: e[0] || (e[0] = at(() => {
563
+ }, ["prevent"])),
564
+ onDragenter: (y) => Z(y, r),
565
+ onDragleave: (y) => tt(y, r),
566
+ onDrop: (y) => X(y, r),
567
+ onDragend: ot
568
+ }, [
569
+ lt(t.$slots, "video", {
570
+ video: S.value[r],
571
+ index: r
572
+ }, () => [
573
+ S.value[r] ? (i(), c("div", _t)) : (i(), c("div", $t, [
574
+ d("div", It, R(W(G.value.indexOf(r))), 1)
575
+ ]))
576
+ ], !0)
577
+ ], 46, Lt);
578
+ }), 128))
579
+ ], 4)
580
+ ])
581
+ ], 4));
582
+ }
583
+ }), Tt = /* @__PURE__ */ F(Gt, [["__scopeId", "data-v-473a71fa"]]), Ot = {
584
+ VideoGridLayout: Tt,
585
+ VideoLayoutIcon: U
586
+ }, Mt = {
587
+ install(l) {
588
+ Object.entries(Ot).forEach(([v, o]) => {
589
+ l.component(v, o);
590
+ });
591
+ }
592
+ };
593
+ export {
594
+ g as LAYOUT_CONFIGS,
595
+ Tt as VideoGridLayout,
596
+ U as VideoLayoutIcon,
597
+ Mt as default,
598
+ ct as getAllLayoutTypes,
599
+ nt as getLayoutPositions
600
+ };
@@ -0,0 +1,15 @@
1
+ import type { LayoutConfig, VideoPosition } from './types';
2
+ /**
3
+ * 所有布局配置
4
+ */
5
+ export declare const LAYOUT_CONFIGS: Record<string, LayoutConfig>;
6
+ /**
7
+ * 获取布局的视频位置配置
8
+ * @param layoutType 布局类型
9
+ * @returns 视频位置数组
10
+ */
11
+ export declare function getLayoutPositions(layoutType: string): VideoPosition[];
12
+ /**
13
+ * 获取所有支持的布局类型列表
14
+ */
15
+ export declare function getAllLayoutTypes(): string[];
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .video-grid-layout{width:100%;height:100%;display:flex;flex-direction:column;background:#0015294d}.layout-toolbar{padding:12px 16px;background:#fff;border-bottom:1px solid #e0e0e0;display:flex;align-items:center;gap:16px;flex-wrap:wrap}.toolbar-title{font-size:14px;font-weight:600;color:#333}.layout-buttons{display:flex;gap:8px;flex-wrap:wrap}.layout-btn{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #d0d0d0;background:#fff;border-radius:4px;cursor:pointer;transition:all .2s;font-size:12px;color:#666}.layout-btn:hover{border-color:#42b883;color:#42b883;background:#f0fdf4}.layout-btn.active{border-color:#42b883;background:#42b883;color:#fff}.layout-label{font-size:12px}.video-grid-container{flex:1;padding:8px;display:flex;align-items:center;justify-content:center;min-height:0;overflow:hidden;box-sizing:border-box}.video-grid{width:100%;height:100%;max-width:100%;max-height:100%;background:#00409f33;padding:4px;border-radius:4px;box-sizing:border-box}.video-item{position:relative;background:#00152999;border:2px solid rgba(0,64,159,.49);border-radius:4px;overflow:hidden;cursor:move;transition:border-color .2s ease,background .2s ease,box-shadow .2s ease,transform .2s ease;min-height:0;min-width:0;-webkit-user-select:none;user-select:none;-webkit-user-drag:element;will-change:transform}.video-item.dragging{opacity:.5;cursor:grabbing;transform:scale(.98);box-shadow:0 4px 12px #0000004d}.video-item:hover{border-color:#42b883cc;background:#001529cc}.video-item.drag-over{border:1px solid rgba(66,184,131,1)!important;background:#42b88333!important}.video-item:focus{outline:1px solid rgba(66,184,131,1);outline-offset:1px}.video-item.main-video{border-width:1px}.video-item>*{width:100%;height:100%}.video-placeholder{display:flex;align-items:center;justify-content:center;height:100%;color:#3de6ff80;-webkit-user-select:none;user-select:none;background:#00409f4d}.placeholder-number{font-size:48px;font-weight:700;color:#3de6ff99;text-shadow:0 0 10px rgba(61,230,255,.3)}@media (max-width: 768px){.layout-toolbar{flex-direction:column;align-items:flex-start}.layout-label{display:none}}.layout-icon[data-v-31e0404d]{width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center}.layout-icon svg[data-v-31e0404d]{width:100%;height:100%}.video-grid-layout[data-v-473a71fa]{width:100%;height:100%;display:flex;flex-direction:column;background:#0015294d}.layout-toolbar[data-v-473a71fa]{padding:12px 16px;background:#fff;border-bottom:1px solid #e0e0e0;display:flex;align-items:center;gap:16px;flex-wrap:wrap}.toolbar-title[data-v-473a71fa]{font-size:14px;font-weight:600;color:#333}.layout-buttons[data-v-473a71fa]{display:flex;gap:8px;flex-wrap:wrap}.layout-btn[data-v-473a71fa]{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #d0d0d0;background:#fff;border-radius:4px;cursor:pointer;transition:all .2s;font-size:12px;color:#666}.layout-btn[data-v-473a71fa]:hover{border-color:#42b883;color:#42b883;background:#f0fdf4}.layout-btn.active[data-v-473a71fa]{border-color:#42b883;background:#42b883;color:#fff}.layout-label[data-v-473a71fa]{font-size:12px}.video-grid-container[data-v-473a71fa]{flex:1;padding:8px;display:flex;align-items:center;justify-content:center;min-height:0;overflow:hidden;box-sizing:border-box}.video-grid[data-v-473a71fa]{width:100%;height:100%;max-width:100%;max-height:100%;background:#00409f33;padding:4px;border-radius:4px;box-sizing:border-box}.video-item[data-v-473a71fa]{position:relative;background:#00152999;border:2px solid rgba(0,64,159,.49);border-radius:4px;overflow:hidden;cursor:move;transition:border-color .2s ease,background .2s ease,box-shadow .2s ease,transform .2s ease;min-height:0;min-width:0;-webkit-user-select:none;user-select:none;-webkit-user-drag:element;will-change:transform}.video-item.dragging[data-v-473a71fa]{opacity:.5;cursor:grabbing;transform:scale(.98);box-shadow:0 4px 12px #0000004d}.video-item[data-v-473a71fa]:hover{border-color:#42b883cc;background:#001529cc}.video-item.drag-over[data-v-473a71fa]{border:1px solid rgba(66,184,131,1)!important;background:#42b88333!important}.video-item[data-v-473a71fa]:focus{outline:1px solid rgba(66,184,131,1);outline-offset:1px}.video-item.main-video[data-v-473a71fa]{border-width:1px}.video-item[data-v-473a71fa]>*{width:100%;height:100%}.video-placeholder[data-v-473a71fa]{display:flex;align-items:center;justify-content:center;height:100%;color:#3de6ff80;-webkit-user-select:none;user-select:none;background:#00409f4d}.placeholder-number[data-v-473a71fa]{font-size:48px;font-weight:700;color:#3de6ff99;text-shadow:0 0 10px rgba(61,230,255,.3)}@media (max-width: 768px){.layout-toolbar[data-v-473a71fa]{flex-direction:column;align-items:flex-start}.layout-label[data-v-473a71fa]{display:none}}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * 布局类型定义
3
+ * 支持的分屏数量:1/2/3/4/6/7/8/9/10/13/16
4
+ */
5
+ export type LayoutType = '1' | '2' | '3' | '4' | '6' | '7' | '8' | '9' | '10' | '13' | '16';
6
+ /**
7
+ * 视频项基础接口
8
+ */
9
+ export interface BaseVideoItem {
10
+ /** 唯一标识符 */
11
+ id: string | number;
12
+ /** 视频标题(可选) */
13
+ title?: string;
14
+ /** 视频URL(可选) */
15
+ url?: string;
16
+ }
17
+ /**
18
+ * 布局配置接口
19
+ */
20
+ export interface LayoutConfig {
21
+ /** 布局类型 */
22
+ type: LayoutType;
23
+ /** 布局名称 */
24
+ label: string;
25
+ /** 视频数量 */
26
+ count: number;
27
+ /** 网格列数 */
28
+ cols: number;
29
+ /** 网格行数 */
30
+ rows: number;
31
+ /** 自定义行高比例(可选),如 '2fr 1fr' */
32
+ rowTemplate?: string;
33
+ /** 自定义列宽比例(可选),如 '2fr 1fr 1fr' */
34
+ colTemplate?: string;
35
+ }
36
+ /**
37
+ * 视频位置配置
38
+ */
39
+ export interface VideoPosition {
40
+ /** 网格列起始位置 */
41
+ col: number;
42
+ /** 网格列结束位置 */
43
+ colSpan: number;
44
+ /** 网格行起始位置 */
45
+ row: number;
46
+ /** 网格行结束位置 */
47
+ rowSpan: number;
48
+ /** 是否是主视频 */
49
+ isMain?: boolean;
50
+ }
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "video-split-screen",
3
+ "version": "1.0.1",
4
+ "description": "Vue 3 视频分屏组件(VideoSplitScreen)",
5
+ "keywords": [
6
+ "vue",
7
+ "vue3",
8
+ "video",
9
+ "split-screen",
10
+ "video-grid",
11
+ "monitoring"
12
+ ],
13
+ "author": "Yojack",
14
+ "license": "MIT",
15
+ "main": "dist/index.js",
16
+ "module": "dist/index.mjs",
17
+ "types": "dist/index.d.ts",
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/your-username/video-split-screen"
24
+ },
25
+ "homepage": "https://github.com/your-username/video-split-screen#readme",
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "scripts": {
30
+ "build": "vite build",
31
+ "build:types": "tsc -p tsconfig.json --emitDeclarationOnly",
32
+ "prepare": "npm run build && npm run build:types"
33
+ },
34
+ "peerDependencies": {
35
+ "vue": "^3.4.0"
36
+ },
37
+ "devDependencies": {
38
+ "vite": "^5.0.0",
39
+ "@vitejs/plugin-vue": "^4.0.0",
40
+ "typescript": "^5.0.0"
41
+ }
42
+ }
43
+
44
+