@xrift/world-components 0.10.0 → 0.10.2
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 +83 -0
- package/dist/components/ScreenShareDisplay/hooks.d.ts +4 -1
- package/dist/components/ScreenShareDisplay/hooks.d.ts.map +1 -1
- package/dist/components/ScreenShareDisplay/hooks.js +34 -3
- package/dist/components/ScreenShareDisplay/hooks.js.map +1 -1
- package/dist/components/ScreenShareDisplay/index.d.ts +1 -1
- package/dist/components/ScreenShareDisplay/index.d.ts.map +1 -1
- package/dist/components/ScreenShareDisplay/index.js +5 -4
- package/dist/components/ScreenShareDisplay/index.js.map +1 -1
- package/dist/components/ScreenShareDisplay/types.d.ts +2 -2
- package/dist/components/ScreenShareDisplay/types.d.ts.map +1 -1
- package/dist/contexts/XRiftContext.d.ts +3 -2
- package/dist/contexts/XRiftContext.d.ts.map +1 -1
- package/dist/contexts/XRiftContext.js +11 -2
- package/dist/contexts/XRiftContext.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -359,6 +359,89 @@ function MyWorld() {
|
|
|
359
359
|
- ブラウザのautoplay policyのため、動画は初期状態でミュートされています
|
|
360
360
|
- 物理コライダーは含まれていません。必要な場合は別途追加してください
|
|
361
361
|
|
|
362
|
+
### ScreenShareDisplay コンポーネント
|
|
363
|
+
|
|
364
|
+
画面共有の映像を3D空間内にスクリーンとして表示するコンポーネントです。`ScreenShareContext` から映像と状態を取得します。
|
|
365
|
+
|
|
366
|
+
```tsx
|
|
367
|
+
import { ScreenShareDisplay } from '@xrift/world-components'
|
|
368
|
+
|
|
369
|
+
function MyWorld() {
|
|
370
|
+
return (
|
|
371
|
+
<>
|
|
372
|
+
{/* 基本的な使い方 */}
|
|
373
|
+
<ScreenShareDisplay id="screen-1" />
|
|
374
|
+
|
|
375
|
+
{/* 位置とサイズを指定 */}
|
|
376
|
+
<ScreenShareDisplay
|
|
377
|
+
id="screen-2"
|
|
378
|
+
position={[5, 2, -3]}
|
|
379
|
+
scale={[3, 3 * (9/16)]}
|
|
380
|
+
/>
|
|
381
|
+
</>
|
|
382
|
+
)
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
#### Props
|
|
387
|
+
|
|
388
|
+
| プロパティ | 型 | 必須 | デフォルト | 説明 |
|
|
389
|
+
|-----------|-----|------|-----------|------|
|
|
390
|
+
| `id` | `string` | ✓ | - | スクリーンの一意なID |
|
|
391
|
+
| `position` | `[number, number, number]` | - | `[0, 2, -5]` | スクリーンの位置 |
|
|
392
|
+
| `rotation` | `[number, number, number]` | - | `[0, 0, 0]` | スクリーンの回転 |
|
|
393
|
+
| `scale` | `[number, number]` | - | `[4, 4 * (9/16)]` | スクリーンのサイズ [幅, 高さ] |
|
|
394
|
+
|
|
395
|
+
#### ScreenShareContext
|
|
396
|
+
|
|
397
|
+
画面共有の状態は `ScreenShareContext` を通じて提供されます。`XRiftProvider` に `screenShareImplementation` を渡すことで設定します。
|
|
398
|
+
|
|
399
|
+
```tsx
|
|
400
|
+
import { XRiftProvider, ScreenShareDisplay } from '@xrift/world-components'
|
|
401
|
+
|
|
402
|
+
function App() {
|
|
403
|
+
const screenShareImpl = {
|
|
404
|
+
videoElement: myVideoElement, // HTMLVideoElement
|
|
405
|
+
isSharing: false,
|
|
406
|
+
startScreenShare: () => { /* 共有開始処理 */ },
|
|
407
|
+
stopScreenShare: () => { /* 共有停止処理 */ },
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return (
|
|
411
|
+
<XRiftProvider
|
|
412
|
+
baseUrl="https://..."
|
|
413
|
+
screenShareImplementation={screenShareImpl}
|
|
414
|
+
>
|
|
415
|
+
<MyWorld />
|
|
416
|
+
</XRiftProvider>
|
|
417
|
+
)
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
#### useScreenShareContext フック
|
|
422
|
+
|
|
423
|
+
コンポーネント内で画面共有の状態を取得するフックです。
|
|
424
|
+
|
|
425
|
+
```tsx
|
|
426
|
+
import { useScreenShareContext } from '@xrift/world-components'
|
|
427
|
+
|
|
428
|
+
function MyComponent() {
|
|
429
|
+
const { videoElement, isSharing, startScreenShare, stopScreenShare } = useScreenShareContext()
|
|
430
|
+
|
|
431
|
+
return (
|
|
432
|
+
<button onClick={isSharing ? stopScreenShare : startScreenShare}>
|
|
433
|
+
{isSharing ? '共有を停止' : '共有を開始'}
|
|
434
|
+
</button>
|
|
435
|
+
)
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
#### 注意事項
|
|
440
|
+
|
|
441
|
+
- `XRiftProvider` に `screenShareImplementation` を渡すことが必須です
|
|
442
|
+
- 映像がない場合は「クリックして画面共有」というガイドテキストが表示されます
|
|
443
|
+
- スクリーンをクリックすると `startScreenShare` / `stopScreenShare` が呼び出されます
|
|
444
|
+
|
|
362
445
|
### Skybox コンポーネント
|
|
363
446
|
|
|
364
447
|
画像を使わずにグラデーションで空を表現するシンプルなskyboxコンポーネントです。
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
/**
|
|
3
3
|
* VideoElement から VideoTexture を作成し管理するフック
|
|
4
|
+
* @param videoElement 映像のvideo要素
|
|
5
|
+
* @param screenSize スクリーンのサイズ [幅, 高さ]
|
|
4
6
|
*/
|
|
5
|
-
export declare const useVideoTexture: (videoElement: HTMLVideoElement | null) => {
|
|
7
|
+
export declare const useVideoTexture: (videoElement: HTMLVideoElement | null, screenSize: [number, number]) => {
|
|
6
8
|
texture: THREE.VideoTexture<HTMLVideoElement> | null;
|
|
7
9
|
hasVideo: boolean;
|
|
8
10
|
materialRef: import("react").RefObject<THREE.MeshBasicMaterial>;
|
|
11
|
+
videoSize: [number, number];
|
|
9
12
|
};
|
|
10
13
|
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAuB9B;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,cAAc,gBAAgB,GAAG,IAAI,EACrC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;CA6E7B,CAAA"}
|
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
import { useFrame } from '@react-three/fiber';
|
|
2
2
|
import { useEffect, useRef, useState } from 'react';
|
|
3
3
|
import * as THREE from 'three';
|
|
4
|
+
/**
|
|
5
|
+
* object-fit: contain 用の映像サイズを計算
|
|
6
|
+
*/
|
|
7
|
+
const calculateContainSize = (videoWidth, videoHeight, screenWidth, screenHeight) => {
|
|
8
|
+
const videoAspect = videoWidth / videoHeight;
|
|
9
|
+
const screenAspect = screenWidth / screenHeight;
|
|
10
|
+
if (videoAspect > screenAspect) {
|
|
11
|
+
// 映像が横長 → 幅に合わせて高さを調整
|
|
12
|
+
return [screenWidth, screenWidth / videoAspect];
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
// 映像が縦長 → 高さに合わせて幅を調整
|
|
16
|
+
return [screenHeight * videoAspect, screenHeight];
|
|
17
|
+
}
|
|
18
|
+
};
|
|
4
19
|
/**
|
|
5
20
|
* VideoElement から VideoTexture を作成し管理するフック
|
|
21
|
+
* @param videoElement 映像のvideo要素
|
|
22
|
+
* @param screenSize スクリーンのサイズ [幅, 高さ]
|
|
6
23
|
*/
|
|
7
|
-
export const useVideoTexture = (videoElement) => {
|
|
24
|
+
export const useVideoTexture = (videoElement, screenSize) => {
|
|
8
25
|
const materialRef = useRef(null);
|
|
9
26
|
const [texture, setTexture] = useState(null);
|
|
27
|
+
const [videoSize, setVideoSize] = useState(screenSize);
|
|
10
28
|
const hasVideo = texture !== null;
|
|
11
29
|
// VideoTextureの作成と更新
|
|
12
30
|
useEffect(() => {
|
|
13
31
|
if (!videoElement) {
|
|
14
32
|
setTexture(null);
|
|
33
|
+
setVideoSize(screenSize);
|
|
15
34
|
return;
|
|
16
35
|
}
|
|
17
36
|
const videoTexture = new THREE.VideoTexture(videoElement);
|
|
@@ -20,10 +39,22 @@ export const useVideoTexture = (videoElement) => {
|
|
|
20
39
|
videoTexture.colorSpace = THREE.SRGBColorSpace;
|
|
21
40
|
videoTexture.needsUpdate = true;
|
|
22
41
|
setTexture(videoTexture);
|
|
42
|
+
// 映像のメタデータがロードされたらサイズを計算
|
|
43
|
+
const handleLoadedMetadata = () => {
|
|
44
|
+
const size = calculateContainSize(videoElement.videoWidth, videoElement.videoHeight, screenSize[0], screenSize[1]);
|
|
45
|
+
setVideoSize(size);
|
|
46
|
+
};
|
|
47
|
+
if (videoElement.videoWidth > 0) {
|
|
48
|
+
handleLoadedMetadata();
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
videoElement.addEventListener('loadedmetadata', handleLoadedMetadata);
|
|
52
|
+
}
|
|
23
53
|
return () => {
|
|
54
|
+
videoElement.removeEventListener('loadedmetadata', handleLoadedMetadata);
|
|
24
55
|
videoTexture.dispose();
|
|
25
56
|
};
|
|
26
|
-
}, [videoElement]);
|
|
57
|
+
}, [videoElement, screenSize]);
|
|
27
58
|
// マテリアルにテクスチャをセット
|
|
28
59
|
useEffect(() => {
|
|
29
60
|
if (!materialRef.current || !texture)
|
|
@@ -52,6 +83,6 @@ export const useVideoTexture = (videoElement) => {
|
|
|
52
83
|
const interval = setInterval(checkAndPlay, 1000);
|
|
53
84
|
return () => clearInterval(interval);
|
|
54
85
|
}, [videoElement]);
|
|
55
|
-
return { texture, hasVideo, materialRef };
|
|
86
|
+
return { texture, hasVideo, materialRef, videoSize };
|
|
56
87
|
};
|
|
57
88
|
//# sourceMappingURL=hooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACnD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,5 +4,5 @@ export type { Props as ScreenShareDisplayProps } from './types';
|
|
|
4
4
|
* 映像を3D空間内にスクリーンとして表示するコンポーネント
|
|
5
5
|
* 画面共有やカメラ映像などの表示に使用可能
|
|
6
6
|
*/
|
|
7
|
-
export declare const ScreenShareDisplay: import("react").MemoExoticComponent<({ id, position, rotation,
|
|
7
|
+
export declare const ScreenShareDisplay: import("react").MemoExoticComponent<({ id, position, rotation, width, }: Props) => import("react/jsx-runtime").JSX.Element>;
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,YAAY,EAAE,KAAK,IAAI,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAO/D;;;GAGG;AACH,eAAO,MAAM,kBAAkB,2EAK5B,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,YAAY,EAAE,KAAK,IAAI,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAO/D;;;GAGG;AACH,eAAO,MAAM,kBAAkB,2EAK5B,KAAK,6CA0DN,CAAA"}
|
|
@@ -6,17 +6,18 @@ import { useScreenShareContext } from '../../contexts/ScreenShareContext';
|
|
|
6
6
|
import { Interactable } from '../Interactable';
|
|
7
7
|
import { useVideoTexture } from './hooks';
|
|
8
8
|
// デフォルト値
|
|
9
|
-
const
|
|
9
|
+
const DEFAULT_WIDTH = 4;
|
|
10
10
|
const DEFAULT_POSITION = [0, 2, -5];
|
|
11
11
|
const DEFAULT_ROTATION = [0, 0, 0];
|
|
12
12
|
/**
|
|
13
13
|
* 映像を3D空間内にスクリーンとして表示するコンポーネント
|
|
14
14
|
* 画面共有やカメラ映像などの表示に使用可能
|
|
15
15
|
*/
|
|
16
|
-
export const ScreenShareDisplay = memo(({ id, position = DEFAULT_POSITION, rotation = DEFAULT_ROTATION,
|
|
16
|
+
export const ScreenShareDisplay = memo(({ id, position = DEFAULT_POSITION, rotation = DEFAULT_ROTATION, width = DEFAULT_WIDTH, }) => {
|
|
17
17
|
const { videoElement, isSharing, startScreenShare, stopScreenShare } = useScreenShareContext();
|
|
18
18
|
const interactionText = isSharing ? '画面共有を停止' : '画面共有を開始';
|
|
19
|
-
const
|
|
19
|
+
const screenSize = [width, width * (9 / 16)];
|
|
20
|
+
const { texture, hasVideo, materialRef, videoSize } = useVideoTexture(videoElement, screenSize);
|
|
20
21
|
const handleInteract = useCallback(() => {
|
|
21
22
|
if (isSharing) {
|
|
22
23
|
stopScreenShare();
|
|
@@ -25,6 +26,6 @@ export const ScreenShareDisplay = memo(({ id, position = DEFAULT_POSITION, rotat
|
|
|
25
26
|
startScreenShare();
|
|
26
27
|
}
|
|
27
28
|
}, [isSharing, startScreenShare, stopScreenShare]);
|
|
28
|
-
return (_jsxs("group", { position: position, rotation: rotation, children: [
|
|
29
|
+
return (_jsxs("group", { position: position, rotation: rotation, children: [_jsxs(Interactable, { id: id, onInteract: handleInteract, interactionText: interactionText, children: [_jsxs("mesh", { children: [_jsx("planeGeometry", { args: [screenSize[0], screenSize[1]] }), _jsx("meshBasicMaterial", { side: THREE.FrontSide, toneMapped: false, color: "#1a1a2a" })] }), hasVideo && (_jsxs("mesh", { position: [0, 0, 0.001], children: [_jsx("planeGeometry", { args: [videoSize[0], videoSize[1]] }), _jsx("meshBasicMaterial", { ref: materialRef, map: texture, side: THREE.FrontSide, toneMapped: false })] }))] }), !hasVideo && (_jsx(Text, { position: [0, 0, 0.01], fontSize: width * 0.05, color: "#666666", anchorX: "center", anchorY: "middle", children: "\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u753B\u9762\u5171\u6709" }))] }));
|
|
29
30
|
});
|
|
30
31
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAKzC,SAAS;AACT,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAKzC,SAAS;AACT,MAAM,aAAa,GAAG,CAAC,CAAA;AACvB,MAAM,gBAAgB,GAA6B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAC7D,MAAM,gBAAgB,GAA6B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;AAE5D;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,CAAC,EACtC,EAAE,EACF,QAAQ,GAAG,gBAAgB,EAC3B,QAAQ,GAAG,gBAAgB,EAC3B,KAAK,GAAG,aAAa,GACf,EAAE,EAAE;IACV,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,GAAG,qBAAqB,EAAE,CAAA;IAC9F,MAAM,eAAe,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IACzD,MAAM,UAAU,GAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC9D,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAE/F,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QACtC,IAAI,SAAS,EAAE,CAAC;YACd,eAAe,EAAE,CAAA;QACnB,CAAC;aAAM,CAAC;YACN,gBAAgB,EAAE,CAAA;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,EAAE,eAAe,CAAC,CAAC,CAAA;IAElD,OAAO,CACL,iBAAO,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,aAC3C,MAAC,YAAY,IACX,EAAE,EAAE,EAAE,EACN,UAAU,EAAE,cAAc,EAC1B,eAAe,EAAE,eAAe,aAGhC,2BACE,wBAAe,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,GAAI,EACvD,4BACE,IAAI,EAAE,KAAK,CAAC,SAAS,EACrB,UAAU,EAAE,KAAK,EACjB,KAAK,EAAC,SAAS,GACf,IACG,EAEN,QAAQ,IAAI,CACX,gBAAM,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,aAC3B,wBAAe,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,GAAI,EACrD,4BACE,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,KAAK,CAAC,SAAS,EACrB,UAAU,EAAE,KAAK,GACjB,IACG,CACR,IACY,EAGd,CAAC,QAAQ,IAAI,CACZ,KAAC,IAAI,IACH,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EACtB,QAAQ,EAAE,KAAK,GAAG,IAAI,EACtB,KAAK,EAAC,SAAS,EACf,OAAO,EAAC,QAAQ,EAChB,OAAO,EAAC,QAAQ,6EAGX,CACR,IACK,CACT,CAAA;AACH,CAAC,CAAC,CAAA"}
|
|
@@ -5,7 +5,7 @@ export interface Props {
|
|
|
5
5
|
position?: [number, number, number];
|
|
6
6
|
/** スクリーンの回転 */
|
|
7
7
|
rotation?: [number, number, number];
|
|
8
|
-
/**
|
|
9
|
-
|
|
8
|
+
/** スクリーンの幅(高さは16:9で自動計算) */
|
|
9
|
+
width?: number;
|
|
10
10
|
}
|
|
11
11
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,kBAAkB;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,eAAe;IACf,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,eAAe;IACf,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/ScreenShareDisplay/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,kBAAkB;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,eAAe;IACf,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,eAAe;IACf,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf"}
|
|
@@ -41,9 +41,10 @@ interface Props {
|
|
|
41
41
|
*/
|
|
42
42
|
instanceStateImplementation?: InstanceStateContextValue;
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
44
|
+
* 画面共有の実装(オプション)
|
|
45
|
+
* 指定しない場合はデフォルト実装(no-op)が使用される
|
|
45
46
|
*/
|
|
46
|
-
screenShareImplementation
|
|
47
|
+
screenShareImplementation?: ScreenShareContextValue;
|
|
47
48
|
children: ReactNode;
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"XRiftContext.d.ts","sourceRoot":"","sources":["../../src/contexts/XRiftContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"XRiftContext.d.ts","sourceRoot":"","sources":["../../src/contexts/XRiftContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAA8C,MAAM,OAAO,CAAA;AACjG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACrC,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,wBAAwB,CAAA;AAC9F,OAAO,EAAuB,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAUxF,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,aAAa,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC9B;;;OAGG;IACH,mBAAmB,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClC;;OAEG;IACH,oBAAoB,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAA;IAChD;;OAEG;IACH,sBAAsB,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAA;CAKnD;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,mDAAgD,CAAA;AAEzE,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC/B;;;OAGG;IACH,2BAA2B,CAAC,EAAE,yBAAyB,CAAA;IACvD;;;OAGG;IACH,yBAAyB,CAAC,EAAE,uBAAuB,CAAA;IACnD,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,+FAM3B,KAAK,4CAqCP,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,QAAO,iBAQ3B,CAAA"}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useCallback, useContext, useState } from 'react';
|
|
2
|
+
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
|
3
3
|
import { InstanceStateProvider } from './InstanceStateContext';
|
|
4
4
|
import { ScreenShareProvider } from './ScreenShareContext';
|
|
5
|
+
// デフォルトの画面共有実装(開発環境用)
|
|
6
|
+
const createDefaultScreenShareImplementation = () => ({
|
|
7
|
+
videoElement: null,
|
|
8
|
+
isSharing: false,
|
|
9
|
+
startScreenShare: () => console.log('[ScreenShare] startScreenShare called'),
|
|
10
|
+
stopScreenShare: () => console.log('[ScreenShare] stopScreenShare called'),
|
|
11
|
+
});
|
|
5
12
|
/**
|
|
6
13
|
* XRift ワールドの情報を提供するContext
|
|
7
14
|
* ワールド側でこのContextを直接参照して情報を取得できる
|
|
@@ -15,6 +22,8 @@ export const XRiftContext = createContext(null);
|
|
|
15
22
|
export const XRiftProvider = ({ baseUrl, currentTarget = null, instanceStateImplementation, screenShareImplementation, children, }) => {
|
|
16
23
|
// インタラクト可能なオブジェクトの管理
|
|
17
24
|
const [interactableObjects] = useState(() => new Set());
|
|
25
|
+
// 画面共有の実装(指定がない場合はデフォルト実装を使用)
|
|
26
|
+
const screenShareImpl = useMemo(() => screenShareImplementation ?? createDefaultScreenShareImplementation(), [screenShareImplementation]);
|
|
18
27
|
// オブジェクトの登録
|
|
19
28
|
const registerInteractable = useCallback((object) => {
|
|
20
29
|
interactableObjects.add(object);
|
|
@@ -29,7 +38,7 @@ export const XRiftProvider = ({ baseUrl, currentTarget = null, instanceStateImpl
|
|
|
29
38
|
interactableObjects,
|
|
30
39
|
registerInteractable,
|
|
31
40
|
unregisterInteractable,
|
|
32
|
-
}, children: _jsx(ScreenShareProvider, { value:
|
|
41
|
+
}, children: _jsx(ScreenShareProvider, { value: screenShareImpl, children: _jsx(InstanceStateProvider, { implementation: instanceStateImplementation, children: children }) }) }));
|
|
33
42
|
};
|
|
34
43
|
/**
|
|
35
44
|
* XRift ワールドの情報を取得するhook
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"XRiftContext.js","sourceRoot":"","sources":["../../src/contexts/XRiftContext.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAkB,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"XRiftContext.js","sourceRoot":"","sources":["../../src/contexts/XRiftContext.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAkB,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEjG,OAAO,EAAE,qBAAqB,EAAkC,MAAM,wBAAwB,CAAA;AAC9F,OAAO,EAAE,mBAAmB,EAAgC,MAAM,sBAAsB,CAAA;AAExF,sBAAsB;AACtB,MAAM,sCAAsC,GAAG,GAA4B,EAAE,CAAC,CAAC;IAC7E,YAAY,EAAE,IAAI;IAClB,SAAS,EAAE,KAAK;IAChB,gBAAgB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC;IAC5E,eAAe,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC;CAC3E,CAAC,CAAA;AAgCF;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAA2B,IAAI,CAAC,CAAA;AAkBzE;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAC5B,OAAO,EACP,aAAa,GAAG,IAAI,EACpB,2BAA2B,EAC3B,yBAAyB,EACzB,QAAQ,GACF,EAAE,EAAE;IACV,qBAAqB;IACrB,MAAM,CAAC,mBAAmB,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,EAAY,CAAC,CAAA;IAEjE,8BAA8B;IAC9B,MAAM,eAAe,GAAG,OAAO,CAC7B,GAAG,EAAE,CAAC,yBAAyB,IAAI,sCAAsC,EAAE,EAC3E,CAAC,yBAAyB,CAAC,CAC5B,CAAA;IAED,YAAY;IACZ,MAAM,oBAAoB,GAAG,WAAW,CAAC,CAAC,MAAgB,EAAE,EAAE;QAC5D,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACjC,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAEzB,cAAc;IACd,MAAM,sBAAsB,GAAG,WAAW,CAAC,CAAC,MAAgB,EAAE,EAAE;QAC9D,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACpC,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAEzB,OAAO,CACL,KAAC,YAAY,CAAC,QAAQ,IACpB,KAAK,EAAE;YACL,OAAO;YACP,aAAa;YACb,mBAAmB;YACnB,oBAAoB;YACpB,sBAAsB;SACvB,YAED,KAAC,mBAAmB,IAAC,KAAK,EAAE,eAAe,YACzC,KAAC,qBAAqB,IAAC,cAAc,EAAE,2BAA2B,YAC/D,QAAQ,GACa,GACJ,GACA,CACzB,CAAA;AACH,CAAC,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAsB,EAAE;IAC9C,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,CAAC,CAAA;IAExC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;IAC/D,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|