Back to home

Building a Particles JS Hero Section with LiveCanvas and Bootstrap Ninja Bootstrap

Ninja Bootstrap Team

June 14, 2024

Join our Discord

Hey there, it’s Lorenz from the Bootstrap Ninja team. Today, I’m going to show you how we used LiveCanvas to create a stunning Hero Section with Particle.js and a Linear Gradient background. For those who aren’t familiar, LiveCanvas is a powerful, live HTML editor based on Bootstrap 5, making it easier to build responsive websites. Let’s dive in!

What is LiveCanvas?

LiveCanvas is a no-code platform that lets you create beautiful and high-performance web pages with Bootstrap 5. It’s designed for developers and designers who want to build their projects visually without sacrificing code quality. LiveCanvas allows you to edit HTML directly, giving you full control over your code.

What is Bootstrap Ninja?

Bootstrap Ninja is a collection of pre-built Bootstrap components and templates designed to speed up your development process. Our components are fully customizable and built to work seamlessly with Bootstrap 5, making it easier to create modern and responsive web applications.

Hero Section with Particle.js and Linear Gradient


Now, let’s take a look at how we built the Hero Section. Below is the complete code:


<script src="https://cdn.jsdelivr.net/npm/particles.js"></script>
<section class="position-relative min-vh-100 overflow-hidden">
    <div class="position-absolute top-0 start-0 object-fit-cover w-100 h-100" style="background:linear-gradient(to bottom, var(--bs-dark) 0%, var(--bs-dark) 10%, var(--bs-dark) 20%, var(--bs-dark) 40%, rgba(var(--bs-body-bg-rgb), .4) 70%, rgba(var(--bs-body-bg-rgb), .5) 80%, rgba(var(--bs-body-bg-rgb), .8) 90%, var(--bs-body-bg) 100%)"></div>

    <div id="particles-js" class="position-absolute w-100 h-100 z-0" style="mix-blend-mode:difference"></div>

    <!-- Content Container -->
    <div class="container position-relative ">
        <div class="row pt-6 pt-lg-8 mb-5">
            <div class="col-12 text-center">
                <div class="lc-block mw-8 mx-auto mb-4">
                    <h1 class="fw-semibold mb-3 ls-n2 text-dark-25 display-1" editable="inline">The Internet is your Artwork.</h1>
                    <p class="lead ls-n1 text-dark-100 fs-2">AppTeam is where artists craft and deploy stunning artworks.</p>
                </div>
                <div class="lc-block d-grid d-lg-flex justify-content-lg-center">
                    <a class="btn btn-primary btn-lg" href="#" role="button">Explore Plans</a>
                </div>
            </div>
        </div>

        <div class="row">
            <div class="col-12">
                <div class="lc-block mw-8 mx-auto">
                    <div lc-helper="video-bg">
                        <video id="video-5603" class="w-100 rounded z-1" style="object-fit: cover; object-position: 50% 50%;" autoplay="" preload="" muted="" loop="" playsinline="">
                            <!-- adjust object-position to tweak cropping on mobile -->
                            <source src="https://cdn.livecanvas.com/media/videos/ai/background_ai_1.mp4" type="video/mp4">
                        </video>
                    </div>

                    <script>
//////////////// interaction observer VIDEO: pauses when video is not seen
if(!!window.IntersectionObserver){
    let video = document.querySelector('#video-5603');
    let isPaused = true; /* flag for auto-pausing of the video */
    let observer = new IntersectionObserver((entries, observer) => { 
        entries.forEach(entry => {
            if(entry.intersectionRatio!=1  && !video.paused){
                video.pause(); isPaused = true; 
                console.log('video-5603 paused');
            }
            else if(isPaused) {
                video.play(); isPaused=false; 
                console.log('video-5603 play');
            }
        });
    }, {threshold: 0.2});
    observer.observe(video); 
}
////////////////////////////////////////////////////////////////////////
                    </script>
                </div>
            </div>
        </div>
    </div>
</section>

<script>
particlesJS('particles-js', {
  particles: {
    number: { value: 80, density: { enable: true, value_area: 800 } },
    color: { value: getComputedStyle(document.documentElement).getPropertyValue('--bs-primary') },
    shape: {
      type: 'circle',
      stroke: { width: 0, color: '#fff' },
      polygon: { nb_sides: 5 }
    },
    opacity: {
      value: 1,
      random: true,
      anim: { enable: true, speed: 1, opacity_min: 0.1, sync: false }
    },
    size: {
      value: 3,
      random: true,
      anim: { enable: false, speed: 40, size_min: 0.1, sync: false }
    },
    line_linked: {
      enable: false
    },
    move: {
      enable: true,
      speed: 0.5,
      direction: 'none',
      random: true,
      straight: false,
      out_mode: 'out',
      bounce: false,
      attract: { enable: false, rotateX: 600, rotateY: 1200 }
    }
  },
  interactivity: {
    detect_on: 'canvas',
    events: {
      onhover: { enable: false },
      onclick: { enable: false },
      resize: true
    }
  },
  retina_detect: true
});
</script>
            

Code Explanation

Now let’s break down the code piece by piece to understand what’s happening.

1. Including Particle.js

<script src="https://cdn.jsdelivr.net/npm/particles.js"></script>

This line includes the Particle.js library, which is used to create the particle effects in the background. Particle.js is a lightweight JavaScript library for creating particles that can move and interact in various ways.

2. Section Container

<section class="position-relative min-vh-100 overflow-hidden"></section>

This is the main container for our hero section. The class position-relative makes it a positioned element, which allows absolutely positioned children to be placed relative to this container. min-vh-100 ensures the section takes at least the full height of the viewport, and overflow-hidden hides any overflowing content.

3. Linear Gradient Background

<div class="position-absolute top-0 start-0 object-fit-cover w-100 h-100" style="background:linear-gradient(to bottom, var(--bs-dark) 0%, var(--bs-dark)10%, var(--bs-dark) 20%, var(--bs-dark) 40%, rgba(var(--bs-body-bg-rgb), .4) 70%, rgba(var(--bs-body-bg-rgb), .5) 80%, rgba(var(--bs-body-bg-rgb), .8) 90%, var(--bs-body-bg) 100%)"></div>

This div creates a full-screen overlay with a linear gradient background. The position-absolute class ensures it covers the entire section, and object-fit-cover makes sure the background covers the entire area without stretching.

4. Particle.js Container

<div id="particles-js" class="position-absolute w-100 h-100 z-0" style="mix-blend-mode:difference"></div>

This div will hold the Particle.js canvas. The mix-blend-mode:difference style creates a difference blend mode effect, making the particles visually distinct from the background.

5. Content Container

<div class="container position-relative"></div>

This div is a Bootstrap container that holds all the content. The position-relative class ensures that any absolutely positioned elements inside this container are positioned relative to it.

6. Row and Column Layout


<div class="row pt-6 pt-lg-8 mb-5">
    <div class="col-12 text-center">
</div>
        

The row and col-12 classes are part of Bootstrap’s grid system. They create a row with a single column that spans the full width of the container. text-center centers the text within the column.

7. Heading and Paragraph


<div class="lc-block mw-8 mx-auto mb-4">
    <h1 class="fw-semibold mb-3 ls-n2 text-dark-25 display-1" editable="inline">The Internet is your Artwork.</h1>
    <p class="lead ls-n1 text-dark-100 fs-2">AppTeam is where artists craft and deploy stunning artworks.</p>
</div>
        

This div contains the main heading and a paragraph. The lc-block class is a custom class used by LiveCanvas for block-level elements. mw-8 mx-auto centers the block and sets its maximum width. The heading and paragraph use various Bootstrap classes for styling, such as fw-semibold for semi-bold text and display-1 for a large font size.

8. Button


<div class="lc-block d-grid d-lg-flex justify-content-lg-center">
    <a class="btn btn-primary btn-lg" href="#" role="button">Explore Plans</a>
</div>
        

This div contains a button. The d-grid and d-lg-flex classes create a flexible grid layout that adapts at larger screen sizes. The button itself uses Bootstrap’s btn classes for styling.

9. Video Background


<div class="lc-block mw-8 mx-auto">
    <div lc-helper="video-bg">
        <video id="video-5603" class="w-100 rounded z-1" style="object-fit: cover; object-position: 50% 50%;" autoplay="" preload="" muted="" loop="" playsinline="">
            <source src="https://cdn.livecanvas.com/media/videos/ai/background_ai_1.mp4" type="video/mp4">
        </video>
    </div>
</div>
        

This section includes a video background. The lc-block and video-bg classes handle layout and styling. The video itself uses HTML5 video attributes like autoplay, preload, muted, and loop to ensure it plays automatically and continuously without sound.

10. Intersection Observer for Video Playback


<script>
if(!!window.IntersectionObserver){
    let video = document.querySelector('#video-5603');
    let isPaused = true; /* flag for auto-pausing of the video */
    let observer = new IntersectionObserver((entries, observer) => { 
        entries.forEach(entry => {
            if(entry.intersectionRatio!=1  && !video.paused){
                video.pause(); isPaused = true; 
                console.log('video-5603 paused');
            }
            else if(isPaused) {
                video.play(); isPaused=false; 
                console.log('video-5603 play');
            }
        });
    }, {threshold: 0.2});
    observer.observe(video); 
}
</script>
        

This script uses the Intersection Observer API to pause the video when it’s not in view. This helps save resources by not playing the video when the user can’t see it. The observer checks the video’s visibility and pauses or plays it based on whether it’s in view or not.

11. Initializing Particle.js


<script>
particlesJS('particles-js', {
  particles: {
    number: { value: 80, density: { enable: true, value_area: 800 } },
    color: { value: getComputedStyle(document.documentElement).getPropertyValue('--bs-primary') },
    shape: {
      type: 'circle',
      stroke: { width: 0, color: '#fff' },
      polygon: { nb_sides: 5 }
    },
    opacity: {
      value: 1,
      random: true,
      anim: { enable: true, speed: 1, opacity_min: 0.1, sync: false }
    },
    size: {
      value: 3,
      random: true,
      anim: { enable: false, speed: 40, size_min: 0.1, sync: false }
    },
    line_linked: {
      enable: false
    },
    move: {
      enable: true,
      speed: 0.5,
      direction: 'none',
      random: true,
      straight: false,
      out_mode: 'out',
      bounce: false,
      attract: { enable: false, rotateX: 600, rotateY: 1200 }
    }
  },
  interactivity: {
    detect_on: 'canvas',
    events: {
      onhover: { enable: false },
      onclick: { enable: false },
      resize: true
    }
  },
  retina_detect: true
});
</script>

The Particle.js script is initialized with a variety of customizable parameters:

1. Particles

  • number: Specifies the number of particles. The value sets the total number, while density enables automatic adjustment based on area.
  • color: Defines the color of the particles. Here, it uses the primary Bootstrap color.
  • shape: Determines the shape of the particles. Common options include circle, edge, triangle, polygon, and star. The polygon shape has an additional property, nb_sides, to specify the number of sides.
  • opacity: Controls the transparency of particles. The value sets the base opacity, and random allows for variations. The anim object enables animation, with properties like speed and opacity_min for finer control.
  • size: Sets the size of particles. The value specifies the default size, while random allows for size variations. Animation can be controlled via the anim object.
  • line_linked: If enabled, particles are connected with lines. This can be customized with properties like distance, color, opacity, and width.
  • move: Controls particle movement. Parameters include speed, direction, random movement, out_mode (behavior when reaching the edge), and bounce. The attract object can pull particles together based on properties like rotateX and rotateY.

2. Interactivity

  • detect_on: Specifies where interactivity should be detected, typically on the canvas.
  • events: Defines interactive events like onhover and onclick. Each event can have associated actions like enabling particles or triggering animations.

3. Retina Detect

  • retina_detect: Ensures that particles look crisp on high-DPI screens.

By adjusting these parameters, you can create highly customized and visually appealing particle effects that enhance your web page’s interactivity and aesthetics.