three-video-projection 0.0.8 → 0.1.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/README.md CHANGED
@@ -37,12 +37,6 @@ git clone https://github.com/hh-hang/three-video-projection.git
37
37
  # 安装依赖
38
38
  npm install
39
39
 
40
- # 进入示例目录
41
- cd example
42
-
43
- # 安装示例依赖
44
- npm install
45
-
46
40
  # 运行开发服务器
47
41
  npm run dev
48
42
  ```
@@ -88,6 +82,8 @@ const projector = await createVideoProjector({
88
82
  opacity: 1.0, // 投影透明度
89
83
  projBias: 0.0001, // 深度偏移
90
84
  edgeFeather: 0.05, // 边缘羽化程度
85
+ cropRect: [0, 0, 1, 1], // 裁剪区域(UV空间,[x0, y0, x1, y1],范围 0~1)
86
+ quadCorners: [[0, 0], [1, 0], [1, 1], [0, 1]], // 四角点变换(投影UV空间,顺序:左下、右下、右上、左上)
91
87
  isShowHelper: true, // 是否显示相机辅助器
92
88
  });
93
89
 
@@ -126,6 +122,8 @@ projector.dispose();
126
122
  - `opacity?: number` — 全局透明度,默认 `1.0`。
127
123
  - `projBias?: number` — 深度偏移,默认 `0.0001`。
128
124
  - `edgeFeather?: number` — 边缘羽化宽度,默认 `0.05`。
125
+ - `cropRect?: [number, number, number, number]` — 视频纹理裁剪区域,UV 空间 `[x0, y0, x1, y1]`,范围 `0~1`。默认 `[0, 0, 1, 1]`(不裁剪)。
126
+ - `quadCorners?: [[number, number], [number, number], [number, number], [number, number]]` — 四角点变换,在投影 UV 空间中指定四角坐标(顺序:左下、右下、右上、左上),用于梯形/透视校正。默认为单位正方形。
129
127
  - `isShowHelper?: boolean` — 是否显示 `CameraHelper` 来可视化投影相机,默认 `true`。
130
128
 
131
129
  ---
@@ -142,10 +140,12 @@ projector.dispose();
142
140
  - `updateElevationDeg(deg: number): void` — 设置俯仰角(度)。
143
141
  - `updateRollDeg(deg: number): void` — 设置滚转角(度)。
144
142
  - `updateOpacity(opacity: number): void` — 更新投影透明度(0~1)。
143
+ - `updateCropRect(rect: [number, number, number, number]): void` — 动态更新裁剪区域(UV 空间,`[x0, y0, x1, y1]`)。
144
+ - `updateQuadCorners(corners: [[number, number], [number, number], [number, number], [number, number]]): void` — 动态更新四角点变换(投影 UV 空间,顺序:左下、右下、右上、左上)。
145
145
 
146
146
  属性:
147
147
 
148
- - `uniforms` — 暴露给外部的着色器 uniform 对象(包含 `projectorMap`、`projectorDepthMap`、`projectorMatrix`、`intensity`、`projBias`、`edgeFeather`、`opacity` 等)。
148
+ - `uniforms` — 暴露给外部的着色器 uniform 对象(包含 `projectorMap`、`projectorDepthMap`、`projectorMatrix`、`intensity`、`projBias`、`edgeFeather`、`opacity`、`cropRect`、`quadHomography` 等)。
149
149
  - `overlays: THREE.Mesh[]` — 内部创建的 overlay 列表(投影用透明网格)。
150
150
  - `targetMeshes: THREE.Mesh[]` — 当前被投影的目标网格列表。
151
151
  - `projCam: THREE.PerspectiveCamera` — 用于投影的相机。
package/dist/index.d.mts CHANGED
@@ -21,6 +21,8 @@ type ProjectorToolOptions = {
21
21
  opacity?: number;
22
22
  projBias?: number;
23
23
  edgeFeather?: number;
24
+ cropRect?: [number, number, number, number];
25
+ quadCorners?: [[number, number], [number, number], [number, number], [number, number]];
24
26
  isShowHelper?: boolean;
25
27
  };
26
28
  type ProjectorTool = {
@@ -32,6 +34,8 @@ type ProjectorTool = {
32
34
  updateElevationDeg: (deg: number) => void;
33
35
  updateRollDeg: (deg: number) => void;
34
36
  updateOpacity: (opacity: number) => void;
37
+ updateCropRect: (rect: [number, number, number, number]) => void;
38
+ updateQuadCorners: (corners: [[number, number], [number, number], [number, number], [number, number]]) => void;
35
39
  uniforms: any;
36
40
  overlays: THREE.Mesh[];
37
41
  targetMeshes: THREE.Mesh[];
package/dist/index.d.ts CHANGED
@@ -21,6 +21,8 @@ type ProjectorToolOptions = {
21
21
  opacity?: number;
22
22
  projBias?: number;
23
23
  edgeFeather?: number;
24
+ cropRect?: [number, number, number, number];
25
+ quadCorners?: [[number, number], [number, number], [number, number], [number, number]];
24
26
  isShowHelper?: boolean;
25
27
  };
26
28
  type ProjectorTool = {
@@ -32,6 +34,8 @@ type ProjectorTool = {
32
34
  updateElevationDeg: (deg: number) => void;
33
35
  updateRollDeg: (deg: number) => void;
34
36
  updateOpacity: (opacity: number) => void;
37
+ updateCropRect: (rect: [number, number, number, number]) => void;
38
+ updateQuadCorners: (corners: [[number, number], [number, number], [number, number], [number, number]]) => void;
35
39
  uniforms: any;
36
40
  overlays: THREE.Mesh[];
37
41
  targetMeshes: THREE.Mesh[];
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -36,8 +35,33 @@ module.exports = __toCommonJS(index_exports);
36
35
 
37
36
  // src/three-video-projection.ts
38
37
  var THREE = __toESM(require("three"));
38
+ function computeQuadHomography(corners) {
39
+ const [[x0, y0], [x1, y1], [x2, y2], [x3, y3]] = corners;
40
+ const dx1 = x1 - x2, dy1 = y1 - y2;
41
+ const dx2 = x3 - x2, dy2 = y3 - y2;
42
+ const dx3 = x0 - x1 + x2 - x3, dy3 = y0 - y1 + y2 - y3;
43
+ const den = dx1 * dy2 - dx2 * dy1;
44
+ const pg = (dx3 * dy2 - dx2 * dy3) / den;
45
+ const ph = (dx1 * dy3 - dx3 * dy1) / den;
46
+ const m00 = x1 - x0 + pg * x1, m01 = x3 - x0 + ph * x3, m02 = x0;
47
+ const m10 = y1 - y0 + pg * y1, m11 = y3 - y0 + ph * y3, m12 = y0;
48
+ const m20 = pg, m21 = ph, m22 = 1;
49
+ const det = m00 * (m11 * m22 - m12 * m21) - m01 * (m10 * m22 - m12 * m20) + m02 * (m10 * m21 - m11 * m20);
50
+ const inv = new THREE.Matrix3();
51
+ inv.set(
52
+ (m11 * m22 - m12 * m21) / det,
53
+ -(m01 * m22 - m02 * m21) / det,
54
+ (m01 * m12 - m02 * m11) / det,
55
+ -(m10 * m22 - m12 * m20) / det,
56
+ (m00 * m22 - m02 * m20) / det,
57
+ -(m00 * m12 - m02 * m10) / det,
58
+ (m10 * m21 - m11 * m20) / det,
59
+ -(m00 * m21 - m01 * m20) / det,
60
+ (m00 * m11 - m01 * m10) / det
61
+ );
62
+ return inv;
63
+ }
39
64
  async function createVideoProjector(opts) {
40
- var _a, _b, _c, _d, _e, _f, _g;
41
65
  const {
42
66
  scene,
43
67
  renderer,
@@ -50,20 +74,22 @@ async function createVideoProjector(opts) {
50
74
  opacity = 1,
51
75
  projBias = 1e-4,
52
76
  edgeFeather = 0.05,
77
+ cropRect = [0, 0, 1, 1],
78
+ quadCorners = [[0, 0], [1, 0], [1, 1], [0, 1]],
53
79
  isShowHelper = true
54
80
  } = opts;
55
81
  let orientParams = {
56
- azimuthDeg: (_a = orientationParams.azimuthDeg) != null ? _a : 0,
57
- elevationDeg: (_b = orientationParams.elevationDeg) != null ? _b : 0,
58
- rollDeg: (_c = orientationParams.rollDeg) != null ? _c : 0
82
+ azimuthDeg: orientationParams.azimuthDeg ?? 0,
83
+ elevationDeg: orientationParams.elevationDeg ?? 0,
84
+ rollDeg: orientationParams.rollDeg ?? 0
59
85
  };
60
86
  let projCam;
61
87
  let camHelper = null;
62
88
  projCam = new THREE.PerspectiveCamera(
63
- (_d = projCamParams.fov) != null ? _d : 30,
64
- (_e = projCamParams.aspect) != null ? _e : 1,
65
- (_f = projCamParams.near) != null ? _f : 0.5,
66
- (_g = projCamParams.far) != null ? _g : 50
89
+ projCamParams.fov ?? 30,
90
+ projCamParams.aspect ?? 1,
91
+ projCamParams.near ?? 0.5,
92
+ projCamParams.far ?? 50
67
93
  );
68
94
  projCam.position.set(
69
95
  projCamPosition[0],
@@ -86,7 +112,9 @@ async function createVideoProjector(opts) {
86
112
  projectorDepthMap: { value: null },
87
113
  projBias: { value: projBias },
88
114
  edgeFeather: { value: edgeFeather },
89
- opacity: { value: opacity }
115
+ opacity: { value: opacity },
116
+ cropRect: { value: new THREE.Vector4(cropRect[0], cropRect[1], cropRect[2], cropRect[3]) },
117
+ quadHomography: { value: computeQuadHomography(quadCorners) }
90
118
  };
91
119
  const vertexShader = `
92
120
  varying vec3 vWorldPos;
@@ -106,6 +134,8 @@ async function createVideoProjector(opts) {
106
134
  uniform float projBias;
107
135
  uniform float edgeFeather;
108
136
  uniform float opacity;
137
+ uniform vec4 cropRect;
138
+ uniform mat3 quadHomography;
109
139
  varying vec3 vWorldPos;
110
140
  varying vec3 vWorldNormal;
111
141
 
@@ -114,8 +144,7 @@ async function createVideoProjector(opts) {
114
144
  if (projPos.w <= 0.0) discard;
115
145
  vec2 uv = projPos.xy / projPos.w * 0.5 + 0.5;
116
146
  if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) discard;
117
- vec4 color = texture(projectorMap, uv);
118
-
147
+
119
148
  // \u906E\u6321\u5254\u9664
120
149
  float projNDCz = projPos.z / projPos.w;
121
150
  float projDepth01 = projNDCz * 0.5 + 0.5;
@@ -124,13 +153,22 @@ async function createVideoProjector(opts) {
124
153
  discard;
125
154
  }
126
155
 
127
- // \u8FB9\u7F18\u7FBD\u5316
128
- vec2 adjUV = uv;
129
- float minDist = min(min(adjUV.x, 1.0 - adjUV.x), min(adjUV.y, 1.0 - adjUV.y));
156
+ // \u56DB\u89D2\u70B9\u53D8\u6362\uFF08\u6295\u5F71UV \u2192 \u89C6\u9891\u7EB9\u7406UV\uFF09
157
+ vec3 hw = quadHomography * vec3(uv, 1.0);
158
+ vec2 warpedUV = hw.xy / hw.z;
159
+
160
+ // \u81EA\u5B9A\u4E49\u88C1\u526A\u53CA\u7FBD\u5316
161
+ vec2 cropMin = cropRect.xy;
162
+ vec2 cropMax = cropRect.zw;
163
+ if (warpedUV.x < cropMin.x || warpedUV.x > cropMax.x || warpedUV.y < cropMin.y || warpedUV.y > cropMax.y) discard;
164
+ float distX = min(warpedUV.x - cropMin.x, cropMax.x - warpedUV.x);
165
+ float distY = min(warpedUV.y - cropMin.y, cropMax.y - warpedUV.y);
166
+ float minDist = min(distX, distY);
130
167
  float edgeFactor = 1.0;
131
168
  if (edgeFeather > 0.0) {
132
169
  edgeFactor = smoothstep(0.0, edgeFeather, minDist);
133
170
  }
171
+ vec4 color = texture(projectorMap, warpedUV);
134
172
  float effectiveAlpha = color.a * edgeFactor;
135
173
 
136
174
  // \u8F93\u51FA
@@ -283,6 +321,12 @@ async function createVideoProjector(opts) {
283
321
  const clamped = Math.max(0, Math.min(1, v));
284
322
  projectorUniforms.opacity.value = clamped;
285
323
  }
324
+ function updateCropRect(rect) {
325
+ projectorUniforms.cropRect.value.set(rect[0], rect[1], rect[2], rect[3]);
326
+ }
327
+ function updateQuadCorners(corners) {
328
+ projectorUniforms.quadHomography.value.copy(computeQuadHomography(corners));
329
+ }
286
330
  return {
287
331
  addTargetMesh,
288
332
  removeTargetMesh,
@@ -292,6 +336,8 @@ async function createVideoProjector(opts) {
292
336
  updateElevationDeg,
293
337
  updateRollDeg,
294
338
  updateOpacity,
339
+ updateCropRect,
340
+ updateQuadCorners,
295
341
  uniforms: projectorUniforms,
296
342
  overlays,
297
343
  targetMeshes,
@@ -300,7 +346,3 @@ async function createVideoProjector(opts) {
300
346
  orientationParams: orientParams
301
347
  };
302
348
  }
303
- // Annotate the CommonJS export names for ESM import in node:
304
- 0 && (module.exports = {
305
- createVideoProjector
306
- });
package/dist/index.mjs CHANGED
@@ -1,7 +1,32 @@
1
1
  // src/three-video-projection.ts
2
2
  import * as THREE from "three";
3
+ function computeQuadHomography(corners) {
4
+ const [[x0, y0], [x1, y1], [x2, y2], [x3, y3]] = corners;
5
+ const dx1 = x1 - x2, dy1 = y1 - y2;
6
+ const dx2 = x3 - x2, dy2 = y3 - y2;
7
+ const dx3 = x0 - x1 + x2 - x3, dy3 = y0 - y1 + y2 - y3;
8
+ const den = dx1 * dy2 - dx2 * dy1;
9
+ const pg = (dx3 * dy2 - dx2 * dy3) / den;
10
+ const ph = (dx1 * dy3 - dx3 * dy1) / den;
11
+ const m00 = x1 - x0 + pg * x1, m01 = x3 - x0 + ph * x3, m02 = x0;
12
+ const m10 = y1 - y0 + pg * y1, m11 = y3 - y0 + ph * y3, m12 = y0;
13
+ const m20 = pg, m21 = ph, m22 = 1;
14
+ const det = m00 * (m11 * m22 - m12 * m21) - m01 * (m10 * m22 - m12 * m20) + m02 * (m10 * m21 - m11 * m20);
15
+ const inv = new THREE.Matrix3();
16
+ inv.set(
17
+ (m11 * m22 - m12 * m21) / det,
18
+ -(m01 * m22 - m02 * m21) / det,
19
+ (m01 * m12 - m02 * m11) / det,
20
+ -(m10 * m22 - m12 * m20) / det,
21
+ (m00 * m22 - m02 * m20) / det,
22
+ -(m00 * m12 - m02 * m10) / det,
23
+ (m10 * m21 - m11 * m20) / det,
24
+ -(m00 * m21 - m01 * m20) / det,
25
+ (m00 * m11 - m01 * m10) / det
26
+ );
27
+ return inv;
28
+ }
3
29
  async function createVideoProjector(opts) {
4
- var _a, _b, _c, _d, _e, _f, _g;
5
30
  const {
6
31
  scene,
7
32
  renderer,
@@ -14,20 +39,22 @@ async function createVideoProjector(opts) {
14
39
  opacity = 1,
15
40
  projBias = 1e-4,
16
41
  edgeFeather = 0.05,
42
+ cropRect = [0, 0, 1, 1],
43
+ quadCorners = [[0, 0], [1, 0], [1, 1], [0, 1]],
17
44
  isShowHelper = true
18
45
  } = opts;
19
46
  let orientParams = {
20
- azimuthDeg: (_a = orientationParams.azimuthDeg) != null ? _a : 0,
21
- elevationDeg: (_b = orientationParams.elevationDeg) != null ? _b : 0,
22
- rollDeg: (_c = orientationParams.rollDeg) != null ? _c : 0
47
+ azimuthDeg: orientationParams.azimuthDeg ?? 0,
48
+ elevationDeg: orientationParams.elevationDeg ?? 0,
49
+ rollDeg: orientationParams.rollDeg ?? 0
23
50
  };
24
51
  let projCam;
25
52
  let camHelper = null;
26
53
  projCam = new THREE.PerspectiveCamera(
27
- (_d = projCamParams.fov) != null ? _d : 30,
28
- (_e = projCamParams.aspect) != null ? _e : 1,
29
- (_f = projCamParams.near) != null ? _f : 0.5,
30
- (_g = projCamParams.far) != null ? _g : 50
54
+ projCamParams.fov ?? 30,
55
+ projCamParams.aspect ?? 1,
56
+ projCamParams.near ?? 0.5,
57
+ projCamParams.far ?? 50
31
58
  );
32
59
  projCam.position.set(
33
60
  projCamPosition[0],
@@ -50,7 +77,9 @@ async function createVideoProjector(opts) {
50
77
  projectorDepthMap: { value: null },
51
78
  projBias: { value: projBias },
52
79
  edgeFeather: { value: edgeFeather },
53
- opacity: { value: opacity }
80
+ opacity: { value: opacity },
81
+ cropRect: { value: new THREE.Vector4(cropRect[0], cropRect[1], cropRect[2], cropRect[3]) },
82
+ quadHomography: { value: computeQuadHomography(quadCorners) }
54
83
  };
55
84
  const vertexShader = `
56
85
  varying vec3 vWorldPos;
@@ -70,6 +99,8 @@ async function createVideoProjector(opts) {
70
99
  uniform float projBias;
71
100
  uniform float edgeFeather;
72
101
  uniform float opacity;
102
+ uniform vec4 cropRect;
103
+ uniform mat3 quadHomography;
73
104
  varying vec3 vWorldPos;
74
105
  varying vec3 vWorldNormal;
75
106
 
@@ -78,8 +109,7 @@ async function createVideoProjector(opts) {
78
109
  if (projPos.w <= 0.0) discard;
79
110
  vec2 uv = projPos.xy / projPos.w * 0.5 + 0.5;
80
111
  if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) discard;
81
- vec4 color = texture(projectorMap, uv);
82
-
112
+
83
113
  // \u906E\u6321\u5254\u9664
84
114
  float projNDCz = projPos.z / projPos.w;
85
115
  float projDepth01 = projNDCz * 0.5 + 0.5;
@@ -88,13 +118,22 @@ async function createVideoProjector(opts) {
88
118
  discard;
89
119
  }
90
120
 
91
- // \u8FB9\u7F18\u7FBD\u5316
92
- vec2 adjUV = uv;
93
- float minDist = min(min(adjUV.x, 1.0 - adjUV.x), min(adjUV.y, 1.0 - adjUV.y));
121
+ // \u56DB\u89D2\u70B9\u53D8\u6362\uFF08\u6295\u5F71UV \u2192 \u89C6\u9891\u7EB9\u7406UV\uFF09
122
+ vec3 hw = quadHomography * vec3(uv, 1.0);
123
+ vec2 warpedUV = hw.xy / hw.z;
124
+
125
+ // \u81EA\u5B9A\u4E49\u88C1\u526A\u53CA\u7FBD\u5316
126
+ vec2 cropMin = cropRect.xy;
127
+ vec2 cropMax = cropRect.zw;
128
+ if (warpedUV.x < cropMin.x || warpedUV.x > cropMax.x || warpedUV.y < cropMin.y || warpedUV.y > cropMax.y) discard;
129
+ float distX = min(warpedUV.x - cropMin.x, cropMax.x - warpedUV.x);
130
+ float distY = min(warpedUV.y - cropMin.y, cropMax.y - warpedUV.y);
131
+ float minDist = min(distX, distY);
94
132
  float edgeFactor = 1.0;
95
133
  if (edgeFeather > 0.0) {
96
134
  edgeFactor = smoothstep(0.0, edgeFeather, minDist);
97
135
  }
136
+ vec4 color = texture(projectorMap, warpedUV);
98
137
  float effectiveAlpha = color.a * edgeFactor;
99
138
 
100
139
  // \u8F93\u51FA
@@ -247,6 +286,12 @@ async function createVideoProjector(opts) {
247
286
  const clamped = Math.max(0, Math.min(1, v));
248
287
  projectorUniforms.opacity.value = clamped;
249
288
  }
289
+ function updateCropRect(rect) {
290
+ projectorUniforms.cropRect.value.set(rect[0], rect[1], rect[2], rect[3]);
291
+ }
292
+ function updateQuadCorners(corners) {
293
+ projectorUniforms.quadHomography.value.copy(computeQuadHomography(corners));
294
+ }
250
295
  return {
251
296
  addTargetMesh,
252
297
  removeTargetMesh,
@@ -256,6 +301,8 @@ async function createVideoProjector(opts) {
256
301
  updateElevationDeg,
257
302
  updateRollDeg,
258
303
  updateOpacity,
304
+ updateCropRect,
305
+ updateQuadCorners,
259
306
  uniforms: projectorUniforms,
260
307
  overlays,
261
308
  targetMeshes,
package/package.json CHANGED
@@ -1,54 +1,52 @@
1
- {
2
- "name": "three-video-projection",
3
- "version": "0.0.8",
4
- "description": "Projector utility for projecting video textures onto meshes (three.js)",
5
- "main": "./dist/index.cjs",
6
- "module": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "require": "./dist/index.cjs"
13
- }
14
- },
15
- "files": [
16
- "dist"
17
- ],
18
- "keywords": [
19
- "three",
20
- "videoProjection",
21
- "videoFusion"
22
- ],
23
- "author": "hh-hang",
24
- "license": "MIT",
25
- "scripts": {
26
- "dev": "vite",
27
- "build": "tsup src/index.ts --format cjs,esm --dts",
28
- "prepare": "npm run build",
29
- "build:cinema": "npm --prefix ./examples/cinema install && npm --prefix ./examples/cinema run build",
30
- "build:monitor": "npm --prefix ./examples/monitor install && npm --prefix ./examples/monitor run build",
31
- "collect": "node ./scripts/collect.js",
32
- "build:examples": "npm run build:cinema && npm run build:monitor && npm run collect"
33
- },
34
- "peerDependencies": {
35
- "three": "^0.182.0"
36
- },
37
- "devDependencies": {
38
- "@types/node": "^25.0.10",
39
- "@types/three": "^0.182.0",
40
- "@vitejs/plugin-vue": "^6.0.3",
41
- "tsup": "^8.5.1",
42
- "typescript": "^5.0.0",
43
- "vite": "^7.3.1",
44
- "vue": "^3.5.27",
45
- "hls.js": "^1.6.15",
46
- "stats.js": "^0.17.0",
47
- "three-player-controller": "^0.3.1"
48
- },
49
- "repository": {
50
- "type": "git",
51
- "url": "https://github.com/hh-hang/three-video-projection"
52
- },
53
- "homepage": "https://hh-hang.github.io/three-video-projection/"
54
- }
1
+ {
2
+ "name": "three-video-projection",
3
+ "version": "0.1.0",
4
+ "description": "Projector utility for projecting video textures onto meshes (three.js)",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "keywords": [
19
+ "three",
20
+ "videoProjection",
21
+ "videoFusion"
22
+ ],
23
+ "author": "hh-hang",
24
+ "license": "MIT",
25
+ "scripts": {
26
+ "dev": "vite",
27
+ "build": "tsup",
28
+ "prepare": "npm run build",
29
+ "build:example": "vite build"
30
+ },
31
+ "peerDependencies": {
32
+ "three": "^0.182.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^25.0.10",
36
+ "@types/three": "^0.182.0",
37
+ "@vitejs/plugin-vue": "^6.0.3",
38
+ "hls.js": "^1.6.15",
39
+ "sass-embedded": "^1.98.0",
40
+ "stats.js": "^0.17.0",
41
+ "three-player-controller": "^0.3.1",
42
+ "tsup": "^8.5.1",
43
+ "typescript": "^5.0.0",
44
+ "vite": "^7.3.1",
45
+ "vue": "^3.5.27"
46
+ },
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/hh-hang/three-video-projection"
50
+ },
51
+ "homepage": "https://hh-hang.github.io/three-video-projection/"
52
+ }