| 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() | |
| } | |
| } | |
| } | |