• canvas动画:气泡上升效果


    HTML5中的canvas真是个很强大的东西呢!

    这几天突发奇想想做一个气泡上升的动画,经过许久的思考和多次失败,终于做出了如下效果

    由于是录制的gif图,看着会有点卡顿,实际演示是很自然的

    想要做出这种效果需要用到大量的随机数

    先上代码:

    CSS+HTML

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            #canvas1{
                display: block;
                position: absolute;
                bottom: 0;
                transition: all 0.2s ease;
            }
        </style>
    </head>
    <body>
        <canvas id="canvas1">您的浏览器不支持canvas</canvas>
    <script src="qipao.js"></script>
    </body>
    </html>

    JS

    let canvas1 = document.getElementById('canvas1');
    let context1 = canvas1.getContext('2d');
    let canvasH = 300;
    
    function resizeCanvas() {
        if (window.innerHeight > 1920) {
            canvas1.width = window.innerWidth;
        }
        else {
            canvas1.width = 1920;
        }
        canvas1.height = canvasH;
    }//设置canvas宽高
    
    resizeCanvas(canvas1);
    
    let num = 100;//气泡数量
    let ballX = [];//球心的横坐标
    let ballY = [];//球心的纵坐标
    let ballR = [];//球的半径
    let ballF = [];//小球左右摆动幅度
    let speed = [];//小球向上移动速度
    let colours = ["rgb(91,155,213)","rgb(180,199,231)","rgb(0,0,255)","rgb(46,177,182)","rgb(68,114,196)"];//小球颜色
    let finalCol=[];
    
    //在随机位置产生num个随机半径的球,储存变量
    for(let i = 0;i < num; i++) {
        let radius = Math.floor(Math.random() * 15 + 10);
        let x = Math.floor(Math.random() * canvas1.offsetWidth);
        let y = Math.floor(Math.random() * 300);
        let fudu = Math.floor(Math.random() * 10 + 5);
        let sp = Math.floor(Math.random() * 30 + 5);
        let color = colours[Math.floor(Math.random() * colours.length)];
        ballX.push(x);
        ballY.push(y);
        ballR.push(radius);
        ballF.push(fudu);
        speed.push(sp);
        finalCol.push(color);
    }
    
    let reX;
    let reY;
    let ballK=[];
    
    //使小球移动(向上做曲线运动)
    function move(){
        context1.clearRect(0, 0, canvas1.offsetWidth, 300);
        for(let i = 0;i < num; i++) {
            (function (i) {
                if(ballK[i] == null){
                    ballK[i] = 0;
                }
                reX = ballK[i] * speed[i] + ballY[i];
                reY = Math.sin(ballK[i]) * ballF[i] + ballX[i];
                if(reX + ballR[i] <= 0){
                    ballY[i] = 320;
                    ballK[i] = 0;
                    reX = ballK[i] * speed[i] + ballY[i];
                }
                context1.beginPath();
                context1.fillStyle = finalCol[i];
                context1.globalAlpha = 0.5;
                context1.arc(reY, reX, ballR[i], 0, Math.PI * 2);
                context1.fill();
                ballK.splice(i,1,ballK[i]);
                ballK[i]-=0.1;
            })(i);
        }
    }
    setInterval(move,20);//定时器

    整体思路:

    首先定义几个数组,一个是装横坐标,一个装纵坐标,一个装半径,一个装圆的颜色

    绘制若干个圆,圆心的横坐标、纵坐标、半径全部采用随机数的形式得到

    用fill()方法填充圆,fillStyle()方法指定颜色,颜色也全部用随机数得到

    用golbalAlpha设置透明度

    这样每个圆都有了自己的初始位置,颜色,和透明度

    然后开始绘制每个球的运动路线

    绘制路线这里我用了sin函数,通过该变角度,振幅等来改变路线,因此又要定义两个数组,一个装振幅,另外一个装圆移动的速度,这两个变量也用随机数的形式得到

    因为sin函数的轨迹总体是水平方向上的运动,因此如果想实现从下往上,就要把横坐标与纵坐标颠倒过来

    当圆从下往上运动时,如果圆已经移出了canvas的范围也就是圆心的纵坐标-半径<=0,那么改变圆的坐标,这样就可以循环从下往上运动了

    设置定时器,每过20毫秒,使用clearRect清除先前的圆的位置,并在新的位置上绘制圆

    说了这么多,个人认为这个动画的核心是储存变量。

  • 相关阅读:
    请求失败或服务未及时响应。有关详细信息,请参见事件日志或其他适用的错误日志
    12篇学通C#网络编程——第一篇 基础之进程线程(转)
    关于XP和win7前置音频插孔无声音的解决办法
    进程,线程,主线程,异步
    SQL 在什么情况下使用全表扫描
    性能的一些设置
    清除Windows 7通知区域的旧图标
    操作office
    数据库索引
    SCSI
  • 原文地址:https://www.cnblogs.com/FrankLongger/p/9359271.html
Copyright © 2020-2023  润新知