DEV Community

Cover image for Web Components? Make it so!
Danny Engelman
Danny Engelman

Posted on β€’ Edited on

1

Web Components? Make it so!


Zach his <snow-fall> Web Component

Is a single <snow-fall> Web Component creating 200 snow-ball DIVs falling down the screen.


Which made me wonder...

...

What if instead of ONE Web Component...

... each snowball would be a unique <snow-flake>?

... How many <snow-flake> Components can my CPU handle?


https://make-it-snow.github.io/

GitHub source code


<make-it-snow> Web Component

an experiment in more and more Web Components

  • Every snowflake is a unique Web Component <snow-flake> with an SVG image.
  • Snowflakes are animated with CSS to fall down rotating and drift sideways.
  • Snowflakes are removed from the DOM when they reach the bottom of the screen (onanimationend).
  • Instead of a fixed amount of snowflakes more snowflakes are added every second.
  • CSS animation FPS (Frames Per Second) is tracked. When FPS is above a threshold more new snowflakes (Web Components) are added at the top of the screen (5 more every second). Below the treshold less snowflakes are added.

FPS can be changed with UP and DOWN arrow keys (once a second, hold down CTRL for 10x).

On my slow? system I get an equilibrium at around 400 total snowflakes on screen:

alt text


https://make-it-snow.github.io/

GitHub source code



Creating a unique SVG snowflake

Create one "spike" from 3 SVG paths with random width and opacity

<g id="spike">
    ["M70 70v-60", 
    "M45 28l25 18l28-16", 
    "M50 11l20 20l20-20"]
    .map( (dpath) => {
        let width = random(3 , 9);
        let opacity = random(0.2 , 1);
        return `<path opacity="${opacity}" stroke-width="${width}" d="${dpath}"/>`;
    })
</g>
Enter fullscreen mode Exit fullscreen mode

Rotate each spike 4,6 or 8 times

Array(spikecount - 1) // from random([4,6,8])
.fill(360 / spikecount) // calculate degrees offset for each spike
.map((degrees, idx) => {
    let spikerotation = (idx + 1) * degrees; // all spikes make up a snowflake
    // every snowflake is in a shadowDOM, so its save to reference ID values!!
    return `<use href="#spike" transform="rotate(${spikerotation} 70 70)"/>`;
})

Enter fullscreen mode Exit fullscreen mode

That will create all unique SVG snowflakes:


https://make-it-snow.github.io/

GitHub source code


URL parameters and Attributes

The <make-it-snow> Web Component can be configured with URL parameters or Attributes. Also see index.html Page Source.

URL examples

parameters

URL parameters only

Parameter Description Default Value
flakecount Number of snow flakes to start with 300
addflakes Number of snow flakes to add every second 20
maxflakes A treshold when not to add more <snow-flake> 1000
fps FPS threshold, change with (ctrl) arrow up/down keys 30
minstrokewidth minimal SVG path width 3
maxstrokewidth maximum SVG path width 3

<snow-flake> Attributes OR URL parameters

See https://make-it-snow.github.io/index.html page source

Attribute Description Default Value
color (string/csv) snowflake color random[internal colors]
size (decimal) snowflake size 2
rotate (int) initial start state 90
spikecount (int/array) number of snowflake spike [4,6,8]
speed (int) fall down speed (seconds) [4 - 12]
drift (int) sideways motion [-5 - 5]
size default size 1
opacity default opacity 1
cssrotation CSS rotation random(-360,360)

https://make-it-snow.github.io/

GitHub source code


Observations

Feel free to add more in the comments

  • 300 <snow-flake> are 3 STYLE elements + 1 SVG in a shadowDOM
    That is 5 DOM elements for every <snow-flake>

  • I did not do much animation optimization. Feel free to suggest low hanging fruit
    CSS will-change:transform (or not) doesn't seem to have a notable effect

  • Its all CSS animation, I wonder what a fullscreen SVG with SMIL animation would do (requires some refactoring)

  • I now re-create a <snow-flake>; wonder what happens when every new snowflake will also become a totally new Web Component <snow-flake-[nr]>. Since we can not uncreate Web Components, will the customElementRegistry eventually cause a Stack Overflow error?




Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

Visualizing Promises and Async/Await πŸ€“

async await

☝️ Check out this all-time classic DEV post on visualizing Promises and Async/Await πŸ€“

πŸ‘‹ Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay