DEV Community

sandeshsapkota
sandeshsapkota

Posted on

Creating an bubble animation with javascript

Hello everyone ! hope you are doing well !

Today, we are going to build a bubble animation with javascript. Pre-requisite is basic understanding in HTML, CSS And Javascript.

Here is what we are going to build today.

Lets start with what we need for Html

<div id="app">  
</div>
Enter fullscreen mode Exit fullscreen mode

And for CSS

*,  
*:before,  
*:after {  
  margin: 0;  
  padding: 0;  
  box-sizing: border-box;  
}  

body {  
  background: rgba(240, 248, 255, 0.9);  
  overflow: hidden;  
}  

.bubble {  
  position: absolute;  
  top: 0;  
  left: 0;  
  border-radius: 50%;  
  cursor: pointer;  
  transition: linear 2s, transform .2s;  
}  

.bubble:hover {  
  transform: scale(1.7);  
}  

.bubble--bust {  
  transform: scale(1.8);  
}

Enter fullscreen mode Exit fullscreen mode

Here, .bubble is the styling class for the random circle that appears on the dom and .bubble-bust is the class that we add to the bubble right before the bubble dissaper, to make the animation better.

that's it for HTML, and CSS part. this is enough for application. lets go to javascript slowly.

const root = document.querySelector('#app');  
const {innerHeight, innerWidth} = window;
Enter fullscreen mode Exit fullscreen mode

Here root is the node where we append bubble . And we will need innerHeight, innerWidth of the viewport to position the bubble in random values between 0 to innerWidth and 0 to innerHeight on x and y axis repectively.

so we are going to create each bubble by initiating a class Bubble() which is function constructor. lets see what we are going to write inside the constructor

class Bubble {  
    constructor() {  
        this.bubbleSpan = undefined;  
        this.handleNewBubble();  
        this.color = this.randomColor();  

        this.posX = 0;  
        this.posY = 0;  

        // setting height and width of the bubble  
        this.height = this.randomNumber(60, 20);  
        this.width = this.height;  

         this.bubbleEnd.call(this.bubbleSpan,this.randomNumber(6000, 3000))  
    }  
}
Enter fullscreen mode Exit fullscreen mode

from the first three lines we are creating this.handleNewBubble() creates a new node and this.color = this.randomColor() sets the random background color.

this.height = this.randomNumber(60, 20);  
this.width = this.height;

this.bubbleEnd.call(this.bubbleSpan, this.randomNumber(6000, 3000))
Enter fullscreen mode Exit fullscreen mode

This is for setting height and width of the bubble between 20 to 60px. and width will be equal to height. And this.bubbleEnd() function is for removing the bubble between 3 to 6 second after it's appearence.

Lets see all other major function of our app.

    // creates and appends a new bubble in the DOM
    handleNewBubble() {
        this.bubbleSpan = document.createElement('span');
        this.bubbleSpan.classList.add('bubble');
        root.append(this.bubbleSpan);
        this.handlePosition()
        this.bubbleSpan.addEventListener('click', this.bubbleEnd)
    }

    handlePosition() { // positioning the bubble in different random X and Y
        const randomY = this.randomNumber(60, -60);
        const randomX = this.randomNumber(60, -60);

        this.bubbleSpan.style.backgroundColor = this.color;
        this.bubbleSpan.style.height = this.height + "px";
        this.bubbleSpan.style.width = this.height + "px";

        this.posY = this.randomNumber(innerHeight - 20, 20);
        this.posX = this.randomNumber(innerWidth - 20, 20);

        this.bubbleSpan.style.top = this.posY + 'px';
        this.bubbleSpan.style.left = this.posX + 'px';

        const randomSec = this.randomNumber(4000, 200);
        setTimeout(this.handlePosition.bind(this), randomSec); // calling for re-position of bubble
    }

    bubbleEnd(removingTime = 0) {
        setTimeout(() => {
            this.classList.add('bubble--bust');
        }, removingTime === 0 ? removingTime : removingTime - 100);

        setTimeout(() => {
            this.remove();
            bubbles.push(new Bubble())
        }, removingTime)

    }
Enter fullscreen mode Exit fullscreen mode

Long thing short ...

so, handleNewBubble() function insert a new node to the DOM and calls for handlePosition() function. it also asign the event handler if the buble is clicked it will be remove from the DOM because we are calling bubbleEnd() function.

handlePosition() function positon the bubble , styles it with height, width and background-color and re-position it.

And, bubbleEnd() function just remove the bubble node from the DOM and it adds bubble--bust class to the node before removing to make the bubble bigger to create animation.

And finally here is where we call the new Bubble() so new bubble appears on the DOM after every second.

// creating many bubble instance in every second  
setInterval(function () {  
    new Bubble()  
}, 1000)
Enter fullscreen mode Exit fullscreen mode

We made it :) Gracias !

Oldest comments (3)

Collapse
 
sp1sp2sp3 profile image
SP1SP2SP3

Hi, I love your bubble script. You've created a great browser window feature!

However, when I check the dev tools in Chrome, there are hundreds of error messages posted "app.js:492 Uncaught TypeError: Failed to execute 'requestAnimationFrame' on 'Window': parameter 1 is not of type 'Function'." for every bubble that's created or moves or disappears.

I have searched the Internet for solutions and the fix seems very easy for a programmer but unfortunately my skills are way too basic. The problem is with passing functions around using setTimeout or something.

Apparently, fix is easy using "requestAnimationFrame(function() {??.update(); });" or requestAnimationFrame(??.update.bind(??));

Can you fix this with your bubble script??

Thanks!! :-)

Collapse
 
mussacharles60 profile image
Mussa Charles

Hi, I just resolve the error issue by surrounding each line with error by try catch block, and everything runs smoothly, please try it ;)
cheers.

Collapse
 
sandeshsapkota profile image
sandeshsapkota

Thank You @sp1sp2sp3 and @Mussa Charles for pointing out and solving the issue . Sorry was away from here . I have updated the script. thanks