|
import { Color3, type Nullable, type Observer, type Scene } from '@babylonjs/core' |
|
import { type Container, LinearGradient } from '@babylonjs/gui' |
|
import { Timing } from './Timing' |
|
|
|
export function Loading<T extends new (...args: any[]) => Container & { scene: Scene }>(Container: T) { |
|
return class LoadingWrapper extends Container { |
|
private _loadingObserver: Nullable<Observer<any>> = null |
|
private _isLoading: boolean = false |
|
get isLoading() { |
|
return this._isLoading |
|
} |
|
|
|
set isLoading(value) { |
|
this._isLoading = value |
|
if (value) |
|
this._registerLoadingObserver() |
|
else |
|
this._unregisterLoadingObserver() |
|
} |
|
|
|
constructor(...rest: any[]) { |
|
super(...rest) |
|
} |
|
|
|
private _registerLoadingObserver() { |
|
this._unregisterLoadingObserver() |
|
|
|
const timing = new Timing({ duration: 1800, iterations: Number.POSITIVE_INFINITY }) |
|
this._loadingObserver = this.scene.getEngine().onBeginFrameObservable.add(() => { |
|
const { left, width } = this._currentMeasure |
|
const { p } = timing |
|
const COLOR_A = Color3.FromInts(156, 252, 248).toHexString() |
|
const COLOR_B = Color3.FromInts(171, 214, 153).toHexString() |
|
const COLOR_C = Color3.FromInts(158, 168, 255).toHexString() |
|
const colors = [COLOR_A, COLOR_B, COLOR_C, COLOR_A, COLOR_B] |
|
const colorNum = colors.length |
|
const _left = left - (1 - p) * width * (colorNum - 2) |
|
const _width = width * (colorNum - 1) |
|
const gradient = new LinearGradient(_left, 0, _left + _width, 0) |
|
colors.forEach((color, i, self) => { |
|
gradient.addColorStop(i / (self.length - 1), color) |
|
}) |
|
this.backgroundGradient = gradient |
|
}) |
|
} |
|
|
|
private _unregisterLoadingObserver() { |
|
this.backgroundGradient = null |
|
this._loadingObserver?.remove() |
|
} |
|
} |
|
} |
|
|