A UI PanelComponent Razor file that renders a div used for screen shake effects and manages applying/removing CSS shake classes for a duration. It exposes a singleton Instance, chooses stronger shakes by rank, schedules clearing after a delay, and triggers re-render via StateHasChanged.
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@namespace Sandbox
<root>
<div class="screen-shake @_shakeClass"></div>
</root>
@code {
public static ScreenShaker Instance { get; private set; }
string _shakeClass = "";
float _shakeClearAt = 0f;
public string ShakeClass => _shakeClass;
protected override void OnStart()
{
Instance = this;
}
public void Shake(string cls, float duration)
{
if (ShakeRank(cls) <= ShakeRank(_shakeClass) && Time.Now < _shakeClearAt)
return;
_shakeClass = cls;
_shakeClearAt = Time.Now + duration;
StateHasChanged();
_ = ClearAfter(duration);
}
static int ShakeRank(string c) => c switch {
"shake-small" => 1,
"shake-medium" => 2,
"shake-strong" => 3,
"shake-insane" => 4,
_ => 0
};
async System.Threading.Tasks.Task ClearAfter(float s)
{
await GameTask.DelaySeconds(s + 0.05f);
_shakeClass = "";
StateHasChanged();
}
protected override int BuildHash() =>
System.HashCode.Combine(_shakeClass);
}