UI/TransitionOverlay.razor

A UI PanelComponent for a transition overlay that draws a centered square 'wipe' using viewport-height units. It exposes a Cover float (0..1) and computes inline style for the square size; it overrides BuildHash to quantise and include visibility to force rebuilds correctly.

File Access
@using System.Globalization
@using Sandbox
@using Sandbox.UI
@inherits PanelComponent
@namespace BlockParty
@attribute [StyleSheet( "TransitionOverlay.razor.scss" )]

@* Stage-transition "wipe": a centred square (original Swatches.Fade colour) that GameManager
   grows to cover the view when leaving a stage and shrinks to reveal the next one. Port of the
   original BaseStage FadeIn/FadeOut rects. Sized in viewport-height units so it stays square and
   exactly covers the 240x240 play region (full screen height) regardless of aspect ratio. *@
<root>
	@if ( Cover > 0.0001f )
	{
		<div class="square" style="@SquareStyle()"></div>
	}
</root>

@code
{
	/// <summary>How much of the view the square covers, 0 (nothing) .. 1 (full play region).</summary>
	public float Cover { get; set; }

	private string SquareStyle()
	{
		// vh keeps the square sized to the viewport HEIGHT on both axes, so it stays square and
		// covers the full-height 240x240 play area (the pillarbox stays the camera clear colour).
		string v = ( Cover * 100f ).ToString( "0.###", CultureInfo.InvariantCulture );
		return $"width: {v}vh; height: {v}vh;";
	}

	// Rebuild as the square scales; quantised so we don't rebuild on sub-pixel changes.
	// IMPORTANT: also hash the visibility flag (Cover > 0.0001f). Without it, a Cover in
	// (0.0001, 0.0025) quantises to the SAME 0 bucket as Cover == 0, yet the markup still draws a
	// ~1px square there. When a reveal's last sub-frame lands in that window and the next frame
	// snaps Cover to 0, the hash wouldn't change, so the panel never rebuilds and the tiny dark
	// square stays stuck dead-centre until the panel is recreated. Hashing visibility guarantees the
	// final "draw -> hide" step always rebuilds and clears it.
	protected override int BuildHash() => System.HashCode.Combine( (int)(Cover * 400f), Cover > 0.0001f );
}