diff --git a/packages/webgal/src/Core/controller/stage/pixi/PixiController.ts b/packages/webgal/src/Core/controller/stage/pixi/PixiController.ts index e1e8e226..97694dc3 100644 --- a/packages/webgal/src/Core/controller/stage/pixi/PixiController.ts +++ b/packages/webgal/src/Core/controller/stage/pixi/PixiController.ts @@ -413,6 +413,90 @@ export default class PixiStage { } } + /** + * 添加视频背景 + * @param key 背景的标识,一般和背景类型有关 + * @param url 背景图片url + */ + public addVideoBg(key: string, url: string) { + const loader = this.assetLoader; + // 准备用于存放这个背景的 Container + const thisBgContainer = new WebGALPixiContainer(); + + // 是否有相同 key 的背景 + const setBgIndex = this.backgroundObjects.findIndex((e) => e.key === key); + const isBgSet = setBgIndex >= 0; + + // 已经有一个这个 key 的背景存在了 + if (isBgSet) { + // 挤占 + this.removeStageObjectByKey(key); + } + + // 挂载 + this.backgroundContainer.addChild(thisBgContainer); + const bgUuid = uuid(); + this.backgroundObjects.push({ + uuid: bgUuid, + key: key, + pixiContainer: thisBgContainer, + sourceUrl: url, + sourceType: 'video', + sourceExt: this.getExtName(url), + }); + + // 完成加载后执行的函数 + const setup = () => { + // TODO:找一个更好的解法,现在的解法是无论是否复用原来的资源,都设置一个延时以让动画工作正常! + + setTimeout(() => { + console.debug('start loaded video: ' + url); + const video = document.createElement('video'); + const videoResource = new PIXI.VideoResource(video); + videoResource.src = url; + videoResource.source.preload = 'auto'; + videoResource.source.muted = true; + videoResource.source.loop = true; + videoResource.source.autoplay = true; + videoResource.source.src = url; + // @ts-ignore + const texture = PIXI.Texture.from(videoResource); + if (texture && this.getStageObjByUuid(bgUuid)) { + /** + * 重设大小 + */ + texture.baseTexture.resource.load().then(() => { + const originalWidth = videoResource.source.videoWidth; + const originalHeight = videoResource.source.videoHeight; + const scaleX = this.stageWidth / originalWidth; + const scaleY = this.stageHeight / originalHeight; + const targetScale = Math.max(scaleX, scaleY); + const bgSprite = new PIXI.Sprite(texture); + bgSprite.scale.x = targetScale; + bgSprite.scale.y = targetScale; + bgSprite.anchor.set(0.5); + bgSprite.position.y = this.stageHeight / 2; + thisBgContainer.setBaseX(this.stageWidth / 2); + thisBgContainer.setBaseY(this.stageHeight / 2); + thisBgContainer.pivot.set(0, this.stageHeight / 2); + thisBgContainer.addChild(bgSprite); + }); + } + }, 0); + }; + + /** + * 加载器部分 + */ + this.cacheGC(); + if (!loader.resources?.[url]?.texture) { + this.loadAsset(url, setup); + } else { + // 复用 + setup(); + } + } + /** * 添加立绘 * @param key 立绘的标识,一般和立绘位置有关 diff --git a/packages/webgal/src/Stage/MainStage/useSetBg.ts b/packages/webgal/src/Stage/MainStage/useSetBg.ts index a292c0dd..3e4708af 100644 --- a/packages/webgal/src/Stage/MainStage/useSetBg.ts +++ b/packages/webgal/src/Stage/MainStage/useSetBg.ts @@ -54,7 +54,10 @@ function removeBg(bgObject: IStageObject) { function addBg(type?: 'image' | 'spine', ...args: any[]) { const url = args[1]; - if (url.endsWith('.skel')) { + if (url.endsWith('.mp4')) { + // @ts-ignore + return WebGAL.gameplay.pixiStage?.addVideoBg(...args); + } else if (url.endsWith('.skel')) { // @ts-ignore return WebGAL.gameplay.pixiStage?.addSpineBg(...args); } else {