Build an Angular component to display snow ❄️ effect
Tags: angular, typescript
Published: 2020-12-23 00:39:19


2020 is about to an end, and the holiday session is coming. It was such a particular year for you and me. I have been staying in Singapore for more than eight months without traveling anywhere else. Probably, I will not be able to come back home for our upcoming Tet holiday. But tough times will make us stronger, I believe so :)

## Jira clone snow theme

I did a quick snow theme for Jira Clone based on an awesome [codepen](https://codepen.io/alphardex/pen/dyPorwJ), written purely with CSS.

That's my result -> https://jira.trungk18.com/project/issue/2020

![Build a component to display snow ❄️ effect with Angular](https://github.com/trungk18/jira-clone-angular/raw/master/frontend/src/assets/img/merry-christmas-2020.gif)

## Snow component

So let go ahead and create a new `SnowComponent`. We don't need to do anything with that component. The heavy lifting part is the template and styling.

```ts
import { Component } from '@angular/core'

@Component({
  selector: 'app-snow',
  templateUrl: './snow.component.html',
  styleUrls: ['./snow.component.css'],
})
export class SnowComponent {}
```

Open the scss file, and paste the below code. Basically, each snowflake will have a random position, opacity, and delay. And we applied it by generating different `keyframe` animation.

The code looks pretty short, but the CSS compiled version could be huge. 😂

```scss
@function random_range($min, $max) {
  $rand: random();
  $random_range: $min + floor($rand * (($max - $min) + 1));
  @return $random_range;
}

.snow {
  $total: 200;
  position: absolute;
  width: 20px;
  height: 20px;
  font-size: 20px;
  border-radius: 50%;
  pointer-events: none;
  color: #a3b1bc;

  @for $i from 1 through $total {
    $random-x: random(1000000) * 0.0001vw;
    $random-offset: random_range(-100000, 100000) * 0.0001vw;
    $random-x-end: $random-x + $random-offset;
    $random-x-end-yoyo: $random-x + ($random-offset / 2);
    $random-yoyo-time: random_range(30000, 80000) / 100000;
    $random-yoyo-y: $random-yoyo-time * 100vh;
    $random-scale: random(10000) * 0.0001;
    $fall-duration: random_range(10, 30) * 1s;
    $fall-delay: random(30) * -1s;

    &:nth-child(#{$i}) {
      opacity: random(8000) * 0.0001;
      transform: translate($random-x, -10px) scale($random-scale);
      animation: fall-#{$i} $fall-duration $fall-delay linear infinite;
    }

    @keyframes fall-#{$i} {
      #{percentage($random-yoyo-time)} {
        transform: translate($random-x-end, $random-yoyo-y) scale($random-scale);
      }

      to {
        transform: translate($random-x-end-yoyo, 100vh) scale($random-scale);
      }
    }
  }
}
```

And last, the snow template. It is just a bunch of `<div class="snow">`, the exact number of `div` should be equal to the `$total` variable we defined on the styling.

```html
<div class="snow">❅</div>
<div class="snow">❅</div>
<div class="snow">❅</div>
<div class="snow">❅</div>
<div class="snow">❅</div>
<!-- code remove for brevity -->
```

And now, you can apply the snow component into your component. That's all. See the result below.

![Build a component to display snow ❄️ effect with Angular](https://dev-to-uploads.s3.amazonaws.com/i/es14c90h3djq5edqtnm3.gif)


## Set overflow hidden for body

Notice on the above result, there was both vertical and horizontal scrollbar. We don't want that to happens.

To fix, add `overflow: hidden` for `body` to style.css.

```css
body {
  overflow: hidden;
}
```

We're done! See the final source code and output below.

## Source code
 

{% stackblitz angular-ivy-snow view=preview %}