introduce
Thanks comehope Big man's [front end daily battle]
Effect preview
Source code address
https://github.com/shanyuhai1...
Code interpretation
1. First, complete the html structure
<figure class="container"> <section class="stars"></section> <section class="fires"></section> </figure>
General style initialization
* { margin: 0; padding: 0; } body { margin: 0; padding: 0 0.5vw; height: 100vh; background-color: #333; overflow: hidden; } .container { display: flex; flex-direction: column; align-items: center; justify-content: center; }
2. Stars in the sky
In the original, the stars are fixed and do not twinkle
And here we will change this state, and in order to avoid repeatedly manually fixing the position and size of the stars, we use the d3 library to reduce the trouble
<script src="https://d3js.org/d3.v5.min.js"></script>
First, change. stars to grid layout
Use span label as star
Because stars flash in time, there is a random -- delay parameter
// index.js const COLUMNS = 15; d3.select('.stars') .style('--columns', COLUMNS) .selectAll('span') .data(d3.range(COLUMNS * COLUMNS)) .enter() .append('span') .style('--delay', () => Math.random() * 20);
Let's start with a general scope and look at the lower boundary
.stars { width: 99vw; height: 70vh; position: absolute; display: grid; grid-template-columns: repeat(var(--columns), 1fr); border: 1px solid; } .stars span { width: 0.6vw; height: 0.6vw; color: whitesmoke; background-color: currentColor; }
The stars are just squares now. Add the rotating flash animation to the squares
.stars span { transform: scale(0); animation: spin 20s linear infinite; animation-delay: calc(var(--delay) * 1s); } @keyframes spin { 0% { transform: rotate(0deg) scale(1); } 5%, 15% { transform: rotate(90deg) scale(0); background: goldenrod; } 17.5% { transform: rotate(180deg) scale(1); background-color: currentColor; } 20%, 100% { transform: rotate(90deg) scale(0); } }
3. Add fire
First, modify DOM
<section class="fires"> <span class="fires__flame"></span> <span class="fires__flame"></span> <span class="fires__flame"></span> <span class="fires__flame"></span> <span class="fires__stick"></span> <span class="fires__stick"></span> </section>
Center the fire and use the media query to change the small problem on the mobile phone
.fires { position: relative; border: 1px solid; } @media screen and (min-width: 451px) { .fires { width: 15vw; height: 15vw; margin-top: -7vw; } } @media screen and (max-width: 450px) { .fires { width: 18vh; height: 18vh; margin-top: -5vw; } }
Then finish the flame effect and add the available color, border radius variables to the parent
.fires { position: relative; display: flex; align-items: center; justify-content: center; border: 1px solid; --color-one: #D92B29; --color-two: #F5732A; --color-three: #F2B338; --color-four: #F5D549; --shape-one: 79% 21% 64% 36% / 43% 61% 39% 57%; --shape-two: 23% 77% 66% 34% / 57% 72% 28% 43%; --shape-three: 78% 22% 63% 37% / 39% 27% 73% 61%; --shape-four: 35% 65% 78% 22% / 54% 50% 50% 46%; } @media screen and (min-width: 451px) { .fires__flame { width: 6vw; } .fires__flame:nth-of-type(1) { height: 15vw; } .fires__flame:nth-of-type(2) { height: 12vw; transform: translate(2.25vw, 1.2vw) rotate(30deg); } .fires__flame:nth-of-type(3) { height: 13.5vw; transform: translate(-2.25vw, 1.2vw) rotate(-30deg); } .fires__flame:nth-of-type(4) { height: 10.5vw; } } @media screen and (max-width: 450px) { .fires__flame { width: 7.2vh; } .fires__flame:nth-of-type(1) { height: 18vh; } .fires__flame:nth-of-type(2) { height: 14.4vh; transform: translate(2.7vh, 1.44vh) rotate(30deg); } .fires__flame:nth-of-type(3) { height: 16.2vh; transform: translate(-2.7vh, 1.44vh) rotate(-30deg); } .fires__flame:nth-of-type(4) { height: 12.6vh; } } .fires__flame { position: absolute; background-color: var(--color-one); border-radius: var(--shape-one); z-index: 0; animation-name: fire; animation-duration: 1.5s; animation-iteration-count: infinite; transition: ease 0.4s; } .fires__flame:nth-of-type(2) { border-radius: var(--shape-two); background-color: var(--color-two); opacity: 0.9; z-index: 2; animation-delay: 0.2s; } .fires__flame:nth-of-type(3) { border-radius: var(--shape-three); background-color: var(--color-three); opacity: 0.8; z-index: 1; animation-delay: 0.4s; } .fires__flame:nth-of-type(4) { border-radius: var(--shape-four); background-color: var(--color-four); opacity: 0.8; z-index: 1; animation-delay: 0.6s; }
Of course, don't forget the animation effect of fire
@keyframes fire { 0% { border-radius: var(--shape-one); background-color: var(--color-one); } 25% { border-radius: var(--shape-two); background-color: var(--color-two); } 50% { border-radius: var(--shape-three); background-color: var(--color-three); } 75% { border-radius: var(--shape-four); background-color: var(--color-four); } 100% { border-radius: var(--shape-one); background-color: var(--color-one); } }
Add firewood
@media screen and (min-width: 451px) { .fires__stick { border-radius: 1.5vw; width: 3vw; height: 13.5vw; bottom: -7.5vw; } } @media screen and (max-width: 450px) { .fires__stick { border-radius: 1.8vh; width: 3.6vh; height: 16.2vh; bottom: -9vh; } } .fires__stick { background-color: #5a3600; position: absolute; z-index: 2; transform:rotate(-70deg); } .fires__stick:last-of-type { transform:rotate(70deg); background-color: #4e2f01; }
4. last
At last, please delete the border frame whose position and size have been confirmed before