angular ui
This commit is contained in:
71
src/app/assetPreloaderService.ts
Normal file
71
src/app/assetPreloaderService.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
interface AssetEntry {
|
||||
path: string;
|
||||
type: 'image' | 'audio';
|
||||
size: number;
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AssetPreloaderService {
|
||||
private totalBytes = 0;
|
||||
private loadedBytes = 0;
|
||||
|
||||
private _progress = new BehaviorSubject<number>(0);
|
||||
progress$ = this._progress.asObservable();
|
||||
|
||||
private images = new Map<string, HTMLImageElement>();
|
||||
private audio = new Map<string, HTMLAudioElement>();
|
||||
|
||||
async preload(): Promise<void> {
|
||||
const manifest: AssetEntry[] = await fetch(
|
||||
'/assets/manifest.json'
|
||||
).then((res) => res.json());
|
||||
this.totalBytes = manifest.reduce((sum, asset) => sum + asset.size, 0);
|
||||
|
||||
const loadTasks = manifest.map((entry) =>
|
||||
this.loadAsset(entry).then((blob) => {
|
||||
const url = URL.createObjectURL(blob);
|
||||
if (entry.type === 'image') {
|
||||
const img = new Image();
|
||||
img.src = url;
|
||||
this.images.set(entry.path, img);
|
||||
} else if (entry.type === 'audio') {
|
||||
const audio = new Audio();
|
||||
audio.src = url;
|
||||
this.audio.set(entry.path, audio);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
await Promise.all(loadTasks);
|
||||
}
|
||||
|
||||
private async loadAsset(entry: AssetEntry): Promise<Blob> {
|
||||
const response = await fetch(`/assets/${entry.path}`);
|
||||
const reader = response.body?.getReader();
|
||||
let loaded = 0;
|
||||
const chunks = [];
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader!.read();
|
||||
if (done)
|
||||
break;
|
||||
chunks.push(value);
|
||||
loaded += value.length;
|
||||
this.loadedBytes += value.length;
|
||||
this._progress.next(this.loadedBytes / this.totalBytes);
|
||||
}
|
||||
|
||||
return new Blob(chunks);
|
||||
}
|
||||
|
||||
getImage(name: string): HTMLImageElement {
|
||||
return this.images.get(name)!;
|
||||
}
|
||||
|
||||
getAudio(name: string): HTMLAudioElement {
|
||||
return this.audio.get(name)!;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user