From e5ffed7eb7ccf780de841c066684497f19f42781 Mon Sep 17 00:00:00 2001 From: MNAth_ Date: Wed, 24 Jan 2024 05:00:14 +0300 Subject: [PATCH] fix: use passed url directly for video url --- src/index.ts | 8 ++-- src/utils/Resources.ts | 97 +++++++++++++++++++++--------------------- 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8e876ec7..1a206b49 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,7 @@ import Sizes, { type SceneSizesType } from "./utils/Sizes"; import Time from "./utils/Time"; import Camera, { type CameraProps } from "./Camera"; import Renderer from "./Renderer"; -import Resources, { type SourceType } from "./utils/Resources"; +import Resources, { type Source } from "./utils/Resources"; import Debug from "./utils/Debug"; /** @@ -86,12 +86,12 @@ export interface InitThreeProps { /** * A list of resources to load. * - * @see {@link SourceType} + * @see {@link Source} * @see {@link Resources} * * @defaultValue `undefined` */ - sources?: SourceType[]; + sources?: Source[]; } export default class QuickThreejs { @@ -144,7 +144,7 @@ export default class QuickThreejs { if (typeof props?.gridSizes === "number") { const GRID_HELPER = new THREE.GridHelper( props?.gridSizes, - props?.gridSizes, + props?.gridSizes ); this.scene.add(GRID_HELPER); } diff --git a/src/utils/Resources.ts b/src/utils/Resources.ts index e39ea469..54050e33 100644 --- a/src/utils/Resources.ts +++ b/src/utils/Resources.ts @@ -1,6 +1,9 @@ import * as THREE from "three"; import EventEmitter from "events"; -import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; +import { + type GLTF, + GLTFLoader, +} from "three/examples/jsm/loaders/GLTFLoader.js"; import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js"; // CLASSES @@ -11,9 +14,9 @@ export type LoadedItemType = | GLTF | THREE.Texture | THREE.CubeTexture - | HTMLVideoElement; + | THREE.VideoTexture; -export interface SourceType { +export interface Source { name: string; type: "cubeTexture" | "texture" | "gltfModel" | "video"; path: string | string[]; @@ -21,8 +24,8 @@ export interface SourceType { export default class Resources extends EventEmitter { app: ThreeApp; - sources: SourceType[] = []; - items: { [name: SourceType["name"]]: LoadedItemType } = {}; + sources: Source[] = []; + items: { [name: Source["name"]]: LoadedItemType } = {}; toLoad = 0; loaded = 0; loaders: { @@ -34,29 +37,24 @@ export default class Resources extends EventEmitter { loadingManager = new THREE.LoadingManager(); private _videoLoader = { - load: (url: string, callback: (element: HTMLVideoElement) => unknown) => { - try { - const urlInstance = new URL(url); - const element = document.createElement("video"); - - element.muted = true; - element.loop = true; - element.controls = true; - element.playsInline = true; - element.autoplay = true; - element.src = urlInstance.href; + load: (url: string, callback: (element: THREE.VideoTexture) => unknown) => { + const element = document.createElement("video"); + + element.muted = true; + element.loop = true; + element.controls = false; + element.playsInline = true; + element.src = url; + element.autoplay = true; + + element.oncanplaythrough = () => { element.play(); - element.oncanplaythrough = () => { - element.play(); - callback(element); - }; - } catch (_) { - return; - } + callback(new THREE.VideoTexture(element)); + }; }, }; - constructor(sources?: SourceType[]) { + constructor(sources?: Source[]) { super(); this.app = new ThreeApp(); @@ -67,26 +65,27 @@ export default class Resources extends EventEmitter { this.setLoaders(); } - setSources(sources: SourceType[]) { - this.toLoad = (this.sources = sources ?? []).length; + setSources(sources: Source[]) { + this.sources = sources; + this.toLoad = (this.sources ?? []).length; this.loaded = 0; return this.toLoad; } - addSource(source: SourceType) { + addSource(source: Source) { this.sources.push(source); - return (this.toLoad = this.sources.length); + this.toLoad = this.sources.length; + return this.toLoad; } - getSource(sourceName: string): SourceType | undefined { + getSource(sourceName: string): Source | undefined { return this.sources.filter((source) => source.name === sourceName)[0]; } removeSource(sourceName: string) { - this.toLoad = (this.sources = this.sources.filter( - (source) => source.name === sourceName, - )).length; + this.sources = this.sources.filter((source) => source.name === sourceName); + this.toLoad = this.sources.length; if (this.loaded > this.toLoad) this.loaded = this.toLoad - 1; @@ -97,7 +96,7 @@ export default class Resources extends EventEmitter { this.loaders.gltfLoader = new GLTFLoader(this.loadingManager); this.loaders.textureLoader = new THREE.TextureLoader(this.loadingManager); this.loaders.cubeTextureLoader = new THREE.CubeTextureLoader( - this.loadingManager, + this.loadingManager ); } @@ -111,41 +110,41 @@ export default class Resources extends EventEmitter { } startLoading() { - this.emit("start", this.loaded); + this.emit("start", this.sources[0], this.loaded, this.toLoad); for (const source of this.sources) { if (!this.items[source.name]) { if (source.type === "gltfModel" && typeof source.path === "string") { - this.loaders.gltfLoader?.load(source.path, (file) => { - this.sourceLoaded(source, file); - }); + this.loaders.gltfLoader?.load(source.path, (file) => + this.sourceLoaded(source, file) + ); } if (source.type === "texture" && typeof source.path === "string") { - this.loaders.textureLoader?.load(source.path, (file) => { - this.sourceLoaded(source, file); - }); + this.loaders.textureLoader?.load(source.path, (file) => + this.sourceLoaded(source, file) + ); } if (source.type === "cubeTexture" && typeof source.path === "object") { - this.loaders.cubeTextureLoader?.load(source.path, (file) => { - this.sourceLoaded(source, file); - }); + this.loaders.cubeTextureLoader?.load(source.path, (file) => + this.sourceLoaded(source, file) + ); } if (source.type === "video" && typeof source.path === "string") { - this._videoLoader.load(source.path, (element) => { - this.sourceLoaded(source, element); - }); + this._videoLoader.load(source.path, (element) => + this.sourceLoaded(source, element) + ); } } } } - sourceLoaded(source: SourceType, file: LoadedItemType) { + sourceLoaded(source: Source, file: LoadedItemType) { this.items[source.name] = file; this.loaded++; - this.emit("progress", this.loaded); + this.emit("progress", source.path, this.loaded, this.toLoad); if (this.loaded === this.toLoad) { - this.emit("ready", this.items); + this.emit("load", source.path, this.loaded, this.toLoad); } } }