-
-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add use video texture, draft * chore: update types * chore: fix types, clean the code * docs: add docs for useVideoTexture * chore: add error handling * chore: use complete words, less cognitive load
- Loading branch information
1 parent
d71ab29
commit f0f1f9b
Showing
6 changed files
with
151 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# useVideoProgress | ||
|
||
A composable to easily use videos as textures in your meshes. | ||
|
||
This composable is based on the Drei [useVideoTexture](https://github.com/pmndrs/drei/tree/master#usevideotexture) | ||
|
||
## Usage | ||
|
||
```ts | ||
import { useVideoTexture } from '@tresjs/cientos' | ||
import exampleVideo from '/myVideoPath' | ||
|
||
const texture = ref() | ||
texture.value = await useVideoTexture(exampleVideo, { loop: false }) | ||
``` | ||
|
||
Then you can use the texture in your material, for example: | ||
|
||
```vue{3} | ||
... | ||
<Sphere :position="[0, 2, 0]"> | ||
<TresMeshBasicMaterial :map="texture" /> | ||
</Sphere> | ||
... | ||
``` | ||
|
||
## Props | ||
|
||
| Prop | Description | Default | | ||
| :------------ | :----------------------------------------------------------------------- | ---------------- | | ||
| `src` | Path to the video. | `undefined` | | ||
| `unsuspend` | Path to the model file. | `loadedmetadata` | | ||
| `crossOrigin` | Whether to use CORS to fetch the related video. | `Anonymous` | | ||
| `muted` | Whether to set the audio silenced. | true | | ||
| `loop` | Automatically seek back to the start upon reaching the end of the video. | true | | ||
| `start` | To play to the video once loaded or not. | true | | ||
| `playsInline` | To be play the video inline or not. | true | | ||
|
||
- Any other attribute for a `<video>` tag is accepted and will automatically set |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<script setup lang="ts"> | ||
import { ref } from 'vue' | ||
import { useVideoTexture, OrbitControls } from '@tresjs/cientos' | ||
import { Sphere } from '../../../src/core' | ||
import { TresCanvas } from '@tresjs/core' | ||
import { SRGBColorSpace, NoToneMapping } from 'three' | ||
const gl = { | ||
clearColor: '#333', | ||
alpha: true, | ||
outputColorSpace: SRGBColorSpace, | ||
toneMapping: NoToneMapping, | ||
useLegacyLights: false, | ||
} | ||
const exampleVideo = 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/video-textures/useVideoTexture.mp4' | ||
const texture = ref() | ||
texture.value = await useVideoTexture(exampleVideo, { loop: false}) | ||
</script> | ||
<template> | ||
<TresCanvas v-bind="gl" ref="canvas"> | ||
<TresPerspectiveCamera :position="[0, 2, 5]" /> | ||
<OrbitControls /> | ||
<Sphere :position="[0, 2, 0]"> | ||
<TresMeshBasicMaterial :map="texture" /> | ||
</Sphere> | ||
<TresGridHelper :size="10" :divisions="10" /> | ||
<TresAmbientLight :intensity="1" /> | ||
</TresCanvas> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
<script setup lang="ts"></script> | ||
<template> | ||
<Suspense> | ||
<OrbitControlsDemo /> | ||
</Suspense> | ||
<Suspense> | ||
<UseVideoTextureDemo /> | ||
</Suspense> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { VideoTexture } from 'three' | ||
import { useLogger } from '../../composables/useLogger' | ||
|
||
interface VideoTextureProps extends HTMLVideoElement { | ||
unsuspend?: 'canplay' | 'canplaythrough' | 'loadstart' | 'loadedmetadata' | ||
start?: boolean | ||
} | ||
|
||
/** | ||
* Composable for loading video textures. | ||
* | ||
* ```ts | ||
* import { ref } from 'vue' | ||
* import { useVideoTexture } from '@tresjs/cientos' | ||
* import MyVideo from 'MyVideo.mp4' | ||
* | ||
* const texture = ref() | ||
* texture.value = await useVideoTexture(MyVideo) | ||
* ``` | ||
* Then you can use the texture in your material. | ||
* | ||
* ```vue | ||
* <TresMeshBasicMaterial :map="texture" /> | ||
* ``` | ||
* @see https://threejs.org/docs/index.html?q=video#api/en/textures/VideoTexture | ||
* @export | ||
* @param {HTMLVideoElement} src | ||
* @return {VideoTexture} {VideoTexture} | ||
*/ | ||
export async function useVideoTexture(src: string | MediaStream, options?: Partial<VideoTextureProps>) { | ||
/** | ||
* Load a video as a texture. | ||
* | ||
* @param {src} string | ||
* @return {VideoTexture} {VideoTexture} | ||
*/ | ||
const { logError } = useLogger() | ||
if (!src) return logError('Error no path provided') | ||
|
||
const { unsuspend, start, crossOrigin, muted, loop, ...rest } = { | ||
unsuspend: 'loadedmetadata', | ||
crossOrigin: 'Anonymous', | ||
muted: true, | ||
loop: true, | ||
start: true, | ||
playsInline: true, | ||
...options, | ||
} | ||
|
||
function loadTexture(): Promise<VideoTexture> { | ||
return new Promise((resolve, reject) => { | ||
const video = Object.assign(document.createElement('video'), { | ||
src: (typeof src === 'string' && src) || undefined, | ||
crossOrigin, | ||
loop, | ||
muted, | ||
autoplay: true, | ||
...rest, | ||
}) | ||
const texture = new VideoTexture(video) | ||
video.addEventListener(unsuspend, () => resolve(texture)) | ||
video.addEventListener('error', () => reject()) | ||
return texture | ||
}) | ||
} | ||
try { | ||
const texture = await loadTexture() | ||
if (start && texture.image) texture.image.play() | ||
return texture | ||
} catch { | ||
logError('Error loading resource') | ||
} | ||
} |