DEV Community

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

Posted on

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
  • 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?



Top comments (0)