This project is an interactive matchstick simulation that runs entirely in the browser. No frameworks. No external libraries. Just HTML, CSS and JavaScript working together to create something that genuinely feels satisfying to use.The idea is simple. You swipe your mouse quickly over the match head and the friction builds up heat. Keep swiping fast enough and the match ignites. The flame flickers and sways like a real one. The match head slowly chars black. The wooden stick gradually burns down from the top. Click anywhere and the flame goes out with a little hiss and a curl of smoke that drifts upward before fading away.What makes this project interesting is that every single effect you see and hear is generated in real time using code. The flame is a CSS shape with blur and animation. The flickering is keyframe animation. The crackling fire sound is synthesized noise through the Web Audio API. The strike sound when you swipe is also generated on the fly. There are no image files. There are no audio files. Everything is math and timing.This kind of project sits in a sweet spot between creative coding and front end engineering. It is not a tutorial exercise where you follow steps to build a form or a navbar. It is a small piece of interactive art that teaches you how the browser can be a canvas for experiences that feel alive. If you have been writing HTML and CSS for a while and you want to start doing things that feel genuinely impressive this is a great project to dig into.
You will learn how to track mouse speed over time by measuring distance between positions and dividing by elapsed milliseconds then use that value to accumulate heat and trigger an ignition event which teaches you to think about user input as something continuous rather than a single click moment. You will learn how CSS class toggling can act as a full state machine where adding or removing a class on the body simultaneously transforms the background glow, the flame visibility, the match head color and the instruction text all at once. You will learn how to layer multiple keyframe animations on a single element to create organic flickering and swaying motion that feels natural. You will learn how CSS transitions on pseudo elements can simulate a physical burn effect moving slowly down the match stick over fifteen seconds. You will also learn how to use the Web Audio API to generate strike sounds, looping fire crackle and an extinguish hiss entirely in JavaScript using buffers, oscillators, gain nodes and biquad filters connected together like a small audio chain. On top of that you will pick up how to unify mouse and touch input into a single handler and how to manage overlapping timers with clearTimeout so your UI state never gets stuck or fires at the wrong moment.
Get an AI-generated overview or a file-by-file code breakdown. Ask questions about the project below the overview.
This project creates an interactive web animation of a match stick that users can "ignite" and "extinguish." The main purpose is to provide a realistic, tactile experience where swiping quickly over the match simulates striking it, causing it to light up with a flickering flame, sparks, and sound. Once lit, the match visually burns down over time, and a click allows the user to extinguish it, revealing smoke and a hiss sound before it resets.
The project's structure is built with a single HTML file that defines the match stick's components, including its head, stick, and separate containers for the flame, sparkles, and smoke.
<div class="match" id="match">
<div class="flame-container" id="flame-container">
<div class="flame"></div>
<div class="sparkles" id="sparkles"></div>
</div>
<div class="match-head" id="match-head"></div>
<div class="match-stick"></div>
</div>This snippet shows the basic HTML structure of the match stick, including its head, stick, and containers for the flame, sparkles, and smoke elements.
CSS is extensively used to style these elements and create all the visual effects. It defines the appearance of the match head, stick, and flame using gradients and shadows. Keyframe animations (@keyframes flicker, @keyframes sway, @keyframes explode, @keyframes smokeRise) bring the flame, sparks, and smoke to life with dynamic movement. The body.lit and body.extinguished classes are crucial for triggering these animations and changing the match's visual state, such as the match head turning black or the stick showing a burnt effect.
.match-stick::after {
content: '';
position: absolute;
/* ... other styles ... */
height: 0%; /* Initially hidden */
transition: height 0s; /* Instant reset */
}
body.lit .match-stick::after {
height: 60%; /* Burnt area grows */
transition: height 15s linear; /* Burns down over 15 seconds */
}This CSS demonstrates how a pseudo-element on the match stick creates a burnt effect that gradually extends downwards over 15 seconds when the body has the lit class.
The JavaScript handles user interaction and state management. It tracks mouse or touch movements (handleMove) to detect fast swipes over the match, accumulating "heat." When enough heat is generated, the ignite() function is called, which adds the lit class to the body to activate the flame and burning animations. Conversely, clicking the body triggers the extinguishing logic, adding the extinguished class to initiate smoke animations and resetting the match's state after a delay.
if (isOverMatch && speed > MIN_SPEED_THRESHOLD) {
heat += speed;
if (currentTime - lastStrikeSoundTime > 80) {
playStrikeSound(speed); // Play strike sound
lastStrikeSoundTime = currentTime;
}
if (heat > IGNITION_HEAT) {
ignite(); // Ignite the match
}
}This JavaScript snippet illustrates the core interaction logic, where fast mouse or touch movements (speed > MINSPEEDTHRESHOLD) over the match accumulate "heat," triggering a strike sound and eventually calling ignite() when enough heat is generated.
A significant feature is the use of the Web Audio API to generate all sound effects programmatically, rather than using pre-recorded audio files. Functions like playStrikeSound, playIgniteSound, and playHissSound create dynamic sounds using oscillators, white noise buffers, filters (bandpass, lowpass, highpass), and gain nodes, providing a highly responsive and realistic audio experience for striking, burning, and extinguishing the match.
function playStrikeSound(intensity) {
initAudio();
if (!audioCtx) return;
const bufferSize = audioCtx.sampleRate * 0.05;
const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
const data = buffer.getChannelData(0);
for (let i = 0; i < bufferSize; i++) {
data[i] = Math.random() * 2 - 1; // Generate white noise
}
const noiseSource = audioCtx.createBufferSource();
noiseSource.buffer = buffer;
const filter = audioCtx.createBiquadFilter();
filter.type = 'bandpass';
filter.frequency.value = 800 + (Math.min(intensity, 5) * 400); // Adjust frequency based on intensity
// ... connect nodes and play ...
}This function demonstrates the use of the Web Audio API to programmatically generate a "strike" sound by creating white noise, applying a bandpass filter whose frequency changes with the strike intensity, and then playing it.
Have a question about how this project works? Ask below and get an answer based on the project code.
Structured technical breakdown for beginners. Anyone can generate or regenerate; your version is saved in this browser (local storage).
No breakdown yet. Generate one to see a file-by-file explanation. Your version is saved in this browser.
Comments
No comments yet. Sign in to leave a comment.
Sign in to leave a comment.