cut-it / src /Loading.ts
KaygNas's picture
Add loading state;
752071c
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()
}
}
}