Skip to content

In this repository you'll find my dramatic process of an attempt to make an only css interactive firework show.

Notifications You must be signed in to change notification settings

juliandecloe/The-anticlimax-fireworkshow

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

My Anticlimax Fireworkshow

Welcome to the beginning of the proces of making my anticlimax firework show. I'll take you to the steps I took and where I went wrong.

See here the website

Week 1: The plan

Have you seen Kung Fu Panda? In the first movie he tries to get over a wall using fireworks and a chair. I want to recreate this. My plan is to remake this scene. I'll make a chair with the panda on it. When you press on a firework arrow attached to the chair, the firework will go off and the panda flies all over the screen.

Week 2: Firework Arrow

It started with the basics. Using images for the panda.

<label for="">
    <img src="img/panda.png" alt="Kung Fu Panda">
    <img src="img/chair.png" alt="Chair">
</label>
img:first-child {
	position: absolute;
	top: 5vh;
	left: 7vw;
	z-index: 1;
}

img:last-child {
	position: absolute;
	top: 8vh;
	left: 3vw;
	width: 280px;
	transform: scaleX(-1);
}

Next I had my first challange: Making a first interactive firework arrow. I tried it using a lot of figures for different elements. I wanted to give it a nice look with a lighthouse kind of pattern on it. For every stripe on the arrow I used a different <figure> element.

This worked, but I knew it could be way easier. My teacher taught me how to use gradients. Now I use a radial-gradient for the middlepart of the arrow,

The only way I could make it interactive was using a <label> element. With the <label> I made a firework arrow using three <figures>. One for the tip, one for the body and one for the stick.

<label for="right-bottom">
    <figure></figure>
    <figure></figure>
    <figure></figure>
</label>
label {
	position: absolute;
	transform: scale(0.3);
	z-index: 5;
	height: 350px;
	width: 120px;
	filter: drop-shadow(2px 2px 4px rgb(0,0,0,0.5));
	transition: 1s;
	cursor: pointer;
	animation: 1s
}

label > figure:first-child {
	clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
	border-radius: 50%;
	position: absolute;
	left: calc(50% - 55px);
	width: 110px;
	height: 130px;
	z-index: 3;
	background-image:	
		conic-gradient(
		at center top,
		transparent 146deg,
		darkgray 146deg,
		lightgray 170deg,
		darkgray 214deg,
		transparent 214deg
	);
	clip-path:ellipse(90% 70% at center top);
}

label figure:nth-child(2) {
	background: blue;
	position: absolute;
	top: 83px;
	left: calc(50% - 37.5px);
	width: 75px;
	height: 160px;
	z-index: 2;
	background-image:
		linear-gradient(
			to right,
			#303a 0%,
			transparent 65%,
			#3036 100%
		),
		repeating-radial-gradient(
			red 0 1em,
			blue 1em 2em
		);
	background-size: 100% 100%, 600% 600%;
	background-position:left top, 40% -30%;
	border-radius: 0 0 50% 50% / 0 0 1em 1em;
}

label > figure:nth-child(3) {
	position: absolute;
	background: #BA8C63;
	top: 220px;
	left: calc(50% - 37.5px);
	width: 10px;
	height: 110px;
	z-index: 1;
	box-shadow: inset -2px 0 8px rgb(0,0,0,0.5);
	clip-path: ellipse(10px 95px at 50% 10%);
}

This is the result:

Week 3: Firework

Making a firework show was harder than I thought. I started using <li> elements wrapped in a <ul> element for every fire work "stroke".

I wanted to rotate and position every li element single handedly, but it came out wrong and sloppy.

li:first-child {
	transform: rotateY(0deg) translateZ(100px);
	background: rgb(0,255,0,0.5);
}

li:nth-child(2) {
	transform: rotateY(30deg) translateZ(100px);
	background: rgb(0,255,0,0.5);
}

etc...

After a lot of messing around I came to the conclusion that this was not the way to do it. I needed to rotate the elements with a calculation so that all elements where rotated the exact degrees. This was harder than I thought because I only want them to rotate over a specific degrees. They can't go further than 60 deg in total over 7 <li> elements. Also I never worked with calc(), so it was something I had to learn. My teacher helped me with the rotate, but it was kind of complicated and therefore hard to understand.

After rotating I started working on the <li> elements moving. This was a bit easier. I just needed to translate the Y position of the <li> elements. I wanted it to grow first, then move and then shrink again, but this gave a really weird effect.

transform: var(--rotate2) scaleY(5) translateY(2em) scaleY(0);

I was not happy with the movement, so I had to find another way. I have tried a lot of messing around with the transforms. I wasted so much time on that part that it had a really big impact on my endresult. I really should have looked at more examples so I could just move on, but I wanted to do it myself.

I thought it would be a good idea to start working on the movement of the panda. I had no idea where to start. I tried moving the panda in a specific direction. Using cubic-bezier I wanted to change the animation into a smooth flying process over the screen. After trying to animate it for 2 hours I decided to not spend anymore time on it. I needed to work on the fireworks, otherwise I have nothing.

Change of plans

Because of the trouble in the text above, I decided to let go of my beautiful idea. So what is the new plan? Making as much fire work arrows as possible and add some cool easter eggs. What exactly? I have no idea. I'll just start working on it and come up with stuff on the way.

To fix the firework my teacher helped me out. He told me to give al elements a background so you have a better look at how all the elements are positioned. This gave me a better overview of what was happening. Instead of only using transform, I started using @keyframes to make animations. This gave me more opportunities to customize the firework animation:

input:first-child[type="checkbox"]:checked ~ main section:first-child > ul > li::after {
	animation: after .3s 1s ease-out forwards;
}

@keyframes after {
	0% {
		transform: scaleY(0);
	}
	33% {
		transform: scaleY(1) ;
	}
	67% {
		transform: translateY(100%) scaleY(1) ;
	}
	100% {
		transform: translateY(200%) scaleY(0) ;
	}
}

After messing around with that I got something like this:

Week 4:

Time to add a second fire arrow!

Cleaning my code

My code was a mess. I had more than 600 lines for a little bit of firework. So it was time to clean up my code. I tried to categorize everything as good as possible:

/*========== GENERAL ==========*/
content


/*========== FIRE ROCKET ==========*/

/*===== GENERAL =====*/
content

/*===== COLOR ARROWS =====*/
content


/*========== FIREWORK ==========*/

/*===== LAYER 1 =====*/
content

/*===== LAYER 2 =====*/
content


/*========== INTERACTION ==========*/

/*===== GENERAL =====*/
content

/*===== ARROW 1 =====*/
content

/*===== ARROW 2 =====*/
content


/*========== ANIMATIONS ==========*/
content

Next to that checked for every element I had what code was necessary and what code I can remove or even combine. Not that it is really important, but eventually my code was so clean that I got 300 lines left. I got way more overview over the code. Now I can keep working on my code without getting lost so quickly.

Background

I wanted stars in the background. Now I could have used div elements and position them en let them grow bigger and smaller using animations, but what would I learn from doing that? I wanted to make a background with stars without adding HTML elemens. So I used multiple radial-gradient properties on the same body background to create little stars. The problem with doing this is: you can't animate radial-gradient with @keyframes.

I came up with the idea to use custom properties for the transparent value in the radial-gradient. Using @keyframes I can change the custom properties to make them bigger and smaller again. Now I had a new problem... Custom properties don't have fixed values. It can be anything, so it doesn't know how to smoothly change the value. I learned that I can tell the browser that a specific custom property will always have a specific syntax. I can to this using @property:

@property --star1 {
	syntax: '<length>';
	inherits: false;
	initial-value: 0px;
}

First I used em. This didn't work. I found out that the initial-value always has to be px. Afterwards you can use any value you want.

Now I could place the custom property in an animation and then after the transparent value in the radial-gradient.

@keyframes stars {
	0% {
		--star1: 5px;
	}
	100% {
		--star1: 10px;
	}
}

radial-gradient(
	circle at
		10%
		20%,
	white,
	transparent var(--star1)
),

For the last firework arrow I wanted to make something different. Something big. But then I realised that I could also do something that suits the title of this project. Why not make it MORE anticlimactic. So lets make a dust cloud at the end.

It kind of works the same. I just had to play around with opacities and ::before and ::after to give it a little bit of a bumpy cloud effect.

Future plans

  • Give the page some fun easter eggs
  • Make more firework arrows
  • Experiment with different kind of explosions
  • Find new ways to play with gradients and colors
  • Firework only on prefers color scheme

Sources

Tools I used:

About

In this repository you'll find my dramatic process of an attempt to make an only css interactive firework show.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • CSS 98.8%
  • HTML 1.2%