preface

Recently I was writing an HTML project, which needed to implement an effect: when the mouse moves over the character, some bubbles of curving movement appear (see the static effect below, please see the full projectzdjzpg.github.io/html5/)), I didn’t have any idea at the beginning, but I collected some information on the Internet and could write it out almost as well. So I wrote a blog to record it, hoping to help others.

Let’s get the canvas ready

  1. Add canvas tag to HTML

<canvas id="test" width="200" height="400"></canvas>

  1. Add a dot style to the page to center the canvas
body{
    background-color: pink;
}
#test{
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    margin: auto;
    border: 1px solid;
}
canvas{
    background-color: white;
}
Copy the code
  1. Js preliminarily get canvas
var canvas=document.getElementById('test')
if(canvas.getContext){
    var ctx=canvas.getContext('2d')// Get 'brush'
}
Copy the code

And then you have to think about what to do? Curved bubbles, as the name suggests, are actually two things: 1. Generate random bubbles.2. Let each bubble move in a curve

How do you randomly create bubbles

Bubbles are actually circles. What is the API for drawing circles on canvas? Arc (x,y,r,startDeg,endDeg), x,y represents the center of the circle,r represents the radius,startDeg,endDeg represents the starting Angle and the ending Angle. Since the shape of the drawing is fixed,startDeg and endDeg are also fixed. So we just randomly generate x,y, and R, and keep painting it on the canvas, and we’re generating random bubbles, but what’s the range of x and y? We can observe that the bubble appears at the bottom at the beginning, so the range of X is the width of 0-canvas, and the position of Y needs to be constantly adjusted according to the radius r so that it is at the bottom of canvas. With that said, let’s get started.

var r=Math.random()*10+3
var x=Math.random()*canvas.clientWidth
var y=canvas.clientHeight-r
Copy the code

This only makes one bubble, what do you do with a lot of bubbles? We can set the timer, periodically create a bubble, and save it in the array, and then use another timer to constantly take out the data in the array as a parameter to draw the circle, as follows:

var arr=[]
setInterval(function(){
    for(var i=0; i<arr.length; i++){ ctx.save() ctx.arc(arr[i].x,arr[i].y,arr[i].r,0.2*Math.PI)// Take the parameter as the circle parameter
        ctx.fill()
        ctx.beginPath()
        ctx.restore()
    }
},1000/60)
setInterval(function(){
    var r=Math.random()*10+3
    var x=Math.random()*canvas.clientWidth
    var y=canvas.clientHeight-r
    arr.push({
        r,x,y// Push the parameters into the array})},5000/60)
Copy the code

It can be observed that the initial position of the circle has been satisfied as follows:

But we found that the color is fixed, so we also need to give the bubble a random color, the code is as follows:

var arr=[]
setInterval(function(){
    ctx.clearRect(0.0,canvas.clientWidth,canvas.clientHe
    for(var i=0; i<arr.length; i++){ arr[i].deg+=5
        arr[i].x=arr[i].startX+Math.sin(arr[i].deg*Math.
        arr[i].y=arr[i].startY-(arr[i].deg*Math.PI/180)*
    }
    for(var i=0; i<arr.length; i++){ ctx.save() ctx.fillStyle='rgba('+arr[i].red+","+arr[i].gree
        ctx.arc(arr[i].x,arr[i].y,arr[i].r,0.2*Math.PI)
        ctx.fill()
        ctx.beginPath()
        ctx.restore()
    }
},1000/60)
setInterval(function(){
    var red=Math.round(Math.random()*255) 
    var blue=Math.round(Math.random()*255) 
    var green=Math.round(Math.random()*255) 
    var alp=1
    var r=Math.random()*10+3
    var x=Math.random()*canvas.clientWidth
    var y=canvas.clientHeight-r
    var deg=0
    var step=Math.random()*20+10
    var startX=x
    var startY=y
    arr.push({
        red,blue,green,alp,r,x,y,step,startX,startY,deg
    })
},5000/60)
Copy the code

The effect is as follows:

It seems to have done the trick, but is it over? Of course not. We haven’t considered the most important arR array in this implementation. What is it doing? The timer keeps adding data to him. He’s already bursting. Do we need to store all that data? Of course not, when the bubble jumps out of the canvas range, we don’t need to calculate it any more, and of course we don’t need to keep its information, we can delete it from the array, so every time we calculate its position, we add a judgment to it, and we are done. Of course, there are timers that are not cleared. This depends on your needs. For example, in my project, I move out of the position of the character and the bubble disappears, so I can clear the timer at this time.

if(arr[i].y<20){
    arr.splice(i,1)}Copy the code

That’s when we’re officially done with this little Demo.

conclusion

  • Create the Canvas environment and get the brush
  • Using two timers to generate random bubbles, the initial position needs to be designed, and all information about bubbles is stored in each object of the array
  • According to the curve you want to achieve, to design radians, and then according to the need to zoom in and out, and each time before drawing new to remove the previous
  • Sweep work, remove information from the array to move out of a fixed range of bubbles, as needed to stop the timer, etc

One item below can be a plus-one item for everyone. If you don’t understand something, please leave a comment on it and I’ll try to get back to me in a moment. One item for a better one can be discussed (●’◡’●) and a complete item for this article

 <! DOCTYPEhtml>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            body{
                background-color: pink;
            }
            #test{
                position: absolute;
                top: 0;
                left: 0;
                bottom: 0;
                right: 0;
                margin: auto;
                border: 1px solid;
            }
            canvas{
                background-color: white;
            }
        </style>
    </head>
    <body>
        <canvas id="test" width="200" height="400"></canvas>
    </body>
    <script type="text/javascript">
        var canvas=document.getElementById('test')
        if(canvas.getContext){
            var ctx=canvas.getContext('2d')
            var arr=[]
            setInterval(function(){
                ctx.clearRect(0.0,canvas.clientWidth,canvas.clientHeight)
                for(var i=0; i<arr.length; i++){ arr[i].deg+=5
                    arr[i].x=arr[i].startX+Math.sin(arr[i].deg*Math.PI/180)*arr[i].step
                    arr[i].y=arr[i].startY-(arr[i].deg*Math.PI/180)*arr[i].step
                    if(arr[i].y<20){
                        arr.splice(i,1)}}for(var i=0; i<arr.length; i++){ ctx.save() ctx.fillStyle='rgba('+arr[i].red+","+arr[i].green+","+arr[i].blue+","+arr[i].alp+') '
                    ctx.arc(arr[i].x,arr[i].y,arr[i].r,0.2*Math.PI)
                    ctx.fill()
                    ctx.beginPath()
                    ctx.restore()
                }
            },1000/60)
            setInterval(function(){
                var red=Math.round(Math.random()*255) 
                var blue=Math.round(Math.random()*255) 
                var green=Math.round(Math.random()*255) 
                var alp=1
                var r=Math.random()*10+3
                var x=Math.random()*canvas.clientWidth
                var y=canvas.clientHeight-r
                var deg=0
                var step=Math.random()*20+10
                var startX=x
                var startY=y
                arr.push({
                    red,blue,green,alp,r,x,y,step,startX,startY,deg
                })
            },5000/60)}</script>
</html>
 <! DOCTYPEhtml>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            body{
                background-color: pink;
            }
            #test{
                position: absolute;
                top: 0;
                left: 0;
                bottom: 0;
                right: 0;
                margin: auto;
                border: 1px solid;
            }
            canvas{
                background-color: white;
            }
        </style>
    </head>
    <body>
        <canvas id="test" width="200" height="400"></canvas>
    </body>
    <script type="text/javascript">
        var canvas=document.getElementById('test')
        if(canvas.getContext){
            var ctx=canvas.getContext('2d')
            var arr=[]
            setInterval(function(){
                ctx.clearRect(0.0,canvas.clientWidth,canvas.clientHeight)
                for(var i=0; i<arr.length; i++){ arr[i].deg+=5
                    arr[i].x=arr[i].startX+Math.sin(arr[i].deg*Math.PI/180)*arr[i].step
                    arr[i].y=arr[i].startY-(arr[i].deg*Math.PI/180)*arr[i].step
                    if(arr[i].y<20){
                        arr.splice(i,1)}}for(var i=0; i<arr.length; i++){ ctx.save() ctx.fillStyle='rgba('+arr[i].red+","+arr[i].green+","+arr[i].blue+","+arr[i].alp+') '
                    ctx.arc(arr[i].x,arr[i].y,arr[i].r,0.2*Math.PI)
                    ctx.fill()
                    ctx.beginPath()
                    ctx.restore()
                }
            },1000/60)
            setInterval(function(){
                var red=Math.round(Math.random()*255) 
                var blue=Math.round(Math.random()*255) 
                var green=Math.round(Math.random()*255) 
                var alp=1
                var r=Math.random()*10+3
                var x=Math.random()*canvas.clientWidth
                var y=canvas.clientHeight-r
                var deg=0
                var step=Math.random()*20+10
                var startX=x
                var startY=y
                arr.push({
                    red,blue,green,alp,r,x,y,step,startX,startY,deg
                })
            },5000/60)}</script>
</html>
 <! DOCTYPEhtml>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            body{
                background-color: pink;
            }
            #test{
                position: absolute;
                top: 0;
                left: 0;
                bottom: 0;
                right: 0;
                margin: auto;
                border: 1px solid;
            }
            canvas{
                background-color: white;
            }
        </style>
    </head>
    <body>
        <canvas id="test" width="200" height="400"></canvas>
    </body>
    <script type="text/javascript">
        var canvas=document.getElementById('test')
        if(canvas.getContext){
            var ctx=canvas.getContext('2d')
            var arr=[]
            setInterval(function(){
                ctx.clearRect(0.0,canvas.clientWidth,canvas.clientHeight)
                for(var i=0; i<arr.length; i++){ arr[i].deg+=5
                    arr[i].x=arr[i].startX+Math.sin(arr[i].deg*Math.PI/180)*arr[i].step
                    arr[i].y=arr[i].startY-(arr[i].deg*Math.PI/180)*arr[i].step
                    if(arr[i].y<20){
                        arr.splice(i,1)}}for(var i=0; i<arr.length; i++){ ctx.save() ctx.fillStyle='rgba('+arr[i].red+","+arr[i].green+","+arr[i].blue+","+arr[i].alp+') '
                    ctx.arc(arr[i].x,arr[i].y,arr[i].r,0.2*Math.PI)
                    ctx.fill()
                    ctx.beginPath()
                    ctx.restore()
                }
            },1000/60)
            setInterval(function(){
                var red=Math.round(Math.random()*255) 
                var blue=Math.round(Math.random()*255) 
                var green=Math.round(Math.random()*255) 
                var alp=1
                var r=Math.random()*10+3
                var x=Math.random()*canvas.clientWidth
                var y=canvas.clientHeight-r
                var deg=0
                var step=Math.random()*20+10
                var startX=x
                var startY=y
                arr.push({
                    red,blue,green,alp,r,x,y,step,startX,startY,deg
                })
            },5000/60)}</script>
</html>

Copy the code

Thanks for reading!!