First impressions matter. This demo builds an eye-catching game loading screen — a liquid-fill progress bar with particle splashes, a pulsing logo, shimmer particles, and a smooth "Loading complete" transition. Zero libraries, pure Canvas 2D. Drop this into your HTML5 game as the first screen players see.
A Canvas loading screen with a sinusoidal liquid wave inside a progress bar container, particles that burst from the fill edge, a percentage counter, and a game title that pulses with a glow. The progress fills at a configurable rate and loops for demo purposes — in a real game, tie it to your asset loading callbacks.
Game Loading Screen — JavaScript Canvas
How the liquid fill effect works in Canvas
The liquid fill is a sine wave path clipped to the progress bar rectangle. Draw a wave by looping through X positions and computing y = barTop + Math.sin(x * frequency + time) * amplitude. Close the path back to the bottom-left corner and fill it. The advancing fill width is just fillWidth = barWidth * progress — the wave is drawn up to that point. Together, the animated wave inside a clipping region creates the liquid illusion.
Clip using ctx.save(); ctx.beginPath(); ctx.roundRect(...); ctx.clip(); before drawing the wave. Everything drawn inside the clip region is automatically masked to the bar shape. Call ctx.restore() to remove the clip for subsequent drawing.
// Clip to progress bar shape
ctx.save();
ctx.beginPath();
ctx.roundRect(barX, barY, barWidth, barHeight, radius);
ctx.clip();
// Draw animated liquid wave
ctx.beginPath();
ctx.moveTo(barX, barY + barHeight);
for (let x = barX; x <= barX + fillWidth; x += 4) {
const y = barY + barHeight - barHeight * progress
+ Math.sin(x * 0.06 + waveTime) * waveAmp;
ctx.lineTo(x, y);
}
ctx.closePath();
ctx.fill();
ctx.restore(); // remove clip
Clip + sine wave = liquid fill. Advance waveTime each frame and the liquid appears to slosh.
Connecting to real asset loading
In a real game, tie progress to asset loading callbacks. Using Phaser, listen to the scene's progress event: this.load.on('progress', value => { loadingProgress = value; }). Using plain JavaScript, count loaded images with an onload counter: progress = loadedCount / totalAssets. The visual loading screen is completely decoupled from asset loading — it just reads the number.
Show the loading screen as the first state in your game's state machine. Start asset loading immediately, update progress as callbacks fire, and transition to the title screen when progress >= 1. Add a minimum display time (0.5–1 second) so the screen doesn't flash instantly on fast connections — players need a moment to read the title.
No comments:
Post a Comment