❄️ Snowfall Effect in Angular with canvas-confetti ❄️

Try this neat trick to create a snowfall effect in your Angular project using the canvas-confetti library!

Here’s how to do it:

Skill Prerequisites

  • Fundamental HTML and CSS knowledge
  • Experience with Angular 2+ and TypeScript

Procedure

As in previous tutorials, let’s first install Node and npm

Set up the Angular project by installing the Angular CLI tool

npm install -g @angular/cli

Create a project

ng new snowy-confetti

Enter the project directory

cd snowy-confetti

Run the local development server

ng serve

Check localhost:4200 in your browser

localhost:4200

We want to click a button to trigger the confetti effect. A canvas HTML element will be generated which contains the confetti animation. For the sake of simplicity, we will use a boolean flag to hide the button once it has been clicked to prevent the user from creating multiple canvases.

We will use Angular’s Renderer2 class to create and attach the canvas element to our HTML template. The full API documentation for Renderer2 can be found here:

https://angular.io/api/core/Renderer2

We’ll import the entire canvas-confetti module into our Angular application. Let’s make it accessible through a variable we’ll call confetti. With a few extra configurations, we can make continuous snowfall appear on the screen.

app.component.ts

import { Component, ElementRef, OnInit, Renderer2 } from '@angular/core';
import * as confetti from 'canvas-confetti';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  public duration = 10 * 1000;
  public animationEnd = Date.now() + this.duration;
  public skew = 1;

  public clicked = false;

  constructor(
    private renderer2: Renderer2,
    private elementRef: ElementRef
  ) {}

  randomInRange(min: number, max: number) {
    return Math.random() * (max - min) + min;
  }

  ngOnInit() {
    this.surprise();
  }

  surprise(): void {

    const canvas = this.renderer2.createElement('canvas');
 
    this.renderer2.appendChild(this.elementRef.nativeElement, canvas);
 
    const myConfetti = confetti.create(canvas, {
      resize: true // will fit all screen sizes
    });

    let timeLeft = this.animationEnd - Date.now();
    let ticks = Math.max(200, 500 * (timeLeft / this.duration));
    let skew = Math.max(0.8, this.skew - 0.001);
  
    myConfetti({
      particleCount: 1,
      startVelocity: 0,
      ticks: ticks,
      origin: {
        x: Math.random(),
        // since particles fall down, skew start toward the top
        y: (Math.random() * skew) - 0.2
      },
      colors: ['#ffffff'],
      shapes: ['circle'],
      gravity: this.randomInRange(0.4, 0.6),
      scalar: this.randomInRange(0.4, 1),
      drift: this.randomInRange(-0.4, 0.4),
    });

    if (timeLeft > 0) {
      setTimeout(() => {
        requestAnimationFrame(this.surprise.bind(this));
      }, 130);
    }

    this.clicked = true;
  };
}

app.component.css

canvas {
  position: absolute;
  top: 0;
  height: 100%;
  width: 100%;
}

…and voila. Enjoy winter with this simple but charming effect!

Latest Posts

Leave a comment