js实现随机移动的萤火虫

知识点:3次贝塞尔曲线

请在这里查看示例 ☞ firefly示例

html:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">  
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>    
    <script type="text/javascript" src="../js/jquery-1.11.3.min.js"></script>  
    <script type="text/javascript" src="js/fly.js"></script>  
    <title>demo</title>  
  
    <style>  
        * {  
            margin: 0;   
            padding: 0;  
        }  
        body, html {  
            width: 100%;  
            height: 100%;  
        }  
        .cav {  
            position: absolute;  
            top: 0;  
            left: 0;  
        }   
          
  
    </style>  
</head>  
<body>  
    <canvas class="cav"></canvas>  
<script>  
        
  
  
  
  
  
  
</script>  
</body>  
</html>
fly.js:

;$(function() {  
    var $cav = $('.cav');    
    var $cavParent = $cav.parent();    

    var cav = $cav[0].getContext('2d'),    
        backColor = '#f7fafc',//背景颜色    
        frontColor = 'rgba(200, 200, 200, .8)',//点颜色    
        overPoint = -10000,    
        mouseArr = [overPoint, overPoint, 200];//鼠标位置和极限半径    
    $('body').css('background', backColor);

    var cavW = $cavParent.width(),    
        cavH = $cavParent.height(),    
        dotArr = [],    
        bezierArr = [],    
        num = 20,// 点的个数  
        ran = 500;    
        step = 500;    

    $cav.attr({    
        'width': cavW,    
        'height': cavH,    
    }).css({    
        'background': backColor,    
    });    

    $cav.on('mousemove', function(e) {    
        mouseArr[0] = e.offsetX;    
        mouseArr[1] = e.offsetY;    
    });   
    $cav.on('mouseout', function(e) {    
        mouseArr[0] = overPoint;    
        mouseArr[1] = overPoint;    
    });    

    //生成随机点    
    for(var i=0; i<num; i++) {    
        var cavL1 = Math.random()*cavW,    
            cavT1 = Math.random()*cavH,    
            cavL2 = Math.random()*cavW,    
            cavT2 = Math.random()*cavH,    
            cavL3 = Math.random()*cavW,    
            cavT3 = Math.random()*cavH,    
            cavL4 = Math.random()*cavW,    
            cavT4 = Math.random()*cavH,    
            cavO = Math.random(),//透明度    
            cavR = cavO*8+2,//尺寸    
            cavD = parseInt(Math.random()*ran)+step;//点的个数    
            cavT = 0;//自身计数器    

        dotArr[i] = [[cavL1, cavT1]/*0*/, [cavL2, cavT2]/*1*/, [cavL3, cavT3]/*2*/, [cavL4, cavT4]/*3*/, cavO/*4*/, cavR/*5*/, cavD/*6*/, cavT/*7*/];//存储坐标    

        var cp = [new Point2D(dotArr[i][0][0], dotArr[i][0][1]), new Point2D(dotArr[i][1][0], dotArr[i][1][1]), new Point2D(dotArr[i][2][0], dotArr[i][2][1]), new Point2D(dotArr[i][3][0], dotArr[i][3][1])];      
        var numberOfPoints=dotArr[i][6];      
        var curve=[];      
        ComputeBezier(cp, numberOfPoints, curve);    
        bezierArr[i] = curve;    
    }    

    setInterval(function() {    
        cav.clearRect(0, 0, cavW, cavH);    
        //移动    
        for(var i=0; i<num; i++) {    
            if(dotArr[i][7] >= dotArr[i][6]) {//走到最后一个点    
                var cavL1 = Math.random()*cavW,    
                    cavT1 = Math.random()*cavH,    
                    cavL2 = Math.random()*cavW,    
                    cavT2 = Math.random()*cavH,    
                    cavL3 = Math.random()*cavW,    
                    cavT3 = Math.random()*cavH,    
                    cavL4 = Math.random()*cavW,    
                    cavT4 = Math.random()*cavH,    
                    cavO = Math.random(),//透明度    
                    cavR = cavO*8+2,//尺寸    
                    cavD = parseInt(Math.random()*ran)+step;//点的个数    
                    cavT = 0;//自身计数器    

                dotArr[i] = [[bezierArr[i][dotArr[i][6]-1].x, bezierArr[i][dotArr[i][6]-1].y]/*0*/, [cavL2, cavT2]/*1*/, [cavL3, cavT3]/*2*/, [cavL4, cavT4]/*3*/, dotArr[i][4]/*4*/, dotArr[i][5]/*5*/, cavD/*6*/, cavT/*7*/];//存储坐标    

                var cp = [new Point2D(dotArr[i][0][0], dotArr[i][0][1]), new Point2D(dotArr[i][1][0], dotArr[i][1][1]), new Point2D(dotArr[i][2][0], dotArr[i][2][1]), new Point2D(dotArr[i][3][0], dotArr[i][3][1])];      
                var numberOfPoints=dotArr[i][6];      
                var curve=[];      
                ComputeBezier(cp, numberOfPoints, curve);    
                bezierArr[i] = curve;    
            }else {    
                // 和鼠标交互  
                if(Math.pow(bezierArr[i][dotArr[i][7]].x-mouseArr[0], 2)+Math.pow(bezierArr[i][dotArr[i][7]].y-mouseArr[1], 2) <= Math.pow(mouseArr[2], 2)) {  
                    cav.beginPath();    
                    var globalAlpha = 1-Math.sqrt(Math.pow(bezierArr[i][dotArr[i][7]].x-mouseArr[0], 2)+Math.pow(bezierArr[i][dotArr[i][7]].y-mouseArr[1], 2))/100/2;  
                    globalAlpha = globalAlpha<0?0:globalAlpha;  
                    cav.globalAlpha = globalAlpha;  
                    cav.strokeStyle = frontColor;    
                    cav.lineTo(mouseArr[0],mouseArr[1]);    
                    cav.lineTo(bezierArr[i][dotArr[i][7]].x, bezierArr[i][dotArr[i][7]].y);    
                    cav.stroke();    
                }  
                // 点与点交互  
                for(var j=0; j<num; j++) {    
                    if(i!=j && dotArr[j][7] < dotArr[j][6]) {//走到最后一个点且不是同一个点    
                        if(Math.pow(bezierArr[i][dotArr[i][7]].x-bezierArr[j][dotArr[j][7]].x, 2)+Math.pow(bezierArr[i][dotArr[i][7]].y-bezierArr[j][dotArr[j][7]].y, 2) <= Math.pow(mouseArr[2], 2)) {    
                            cav.beginPath();    
                            var globalAlpha = 1-Math.sqrt(Math.pow(bezierArr[i][dotArr[i][7]].x-bezierArr[j][dotArr[j][7]].x, 2)+Math.pow(bezierArr[i][dotArr[i][7]].y-bezierArr[j][dotArr[j][7]].y, 2))/100/2;  
                            globalAlpha = globalAlpha<0?0:globalAlpha;  
                            cav.globalAlpha = globalAlpha;    
                            cav.strokeStyle = frontColor;    
                            cav.lineTo(bezierArr[j][dotArr[j][7]].x,bezierArr[j][dotArr[j][7]].y);    
                            cav.lineTo(bezierArr[i][dotArr[i][7]].x, bezierArr[i][dotArr[i][7]].y);    
                            cav.stroke();    
                        }  
                    }  
                }  
                cav.beginPath();    
                cav.globalAlpha = dotArr[i][4]*.6;    
                cav.fillStyle = frontColor;    
                cav.arc(bezierArr[i][dotArr[i][7]].x, bezierArr[i][dotArr[i][7]].y, dotArr[i][5], 0, 2*Math.PI);    
                cav.fill();    
            }    
            dotArr[i][7] += 1;    
                
        }    
    }, 20);    

          
        

    function Point2D(x, y){      
        this.x=x||0.0;      
        this.y=y||0.0;      
    }    
    function PointOnCubicBezier(cp, t) {//cp为4个Point2D点,0<=t<=1    
        var ax, bx, cx;      
        var ay, by, cy;      
        var tSquared, tCubed;      
        var result = new Point2D;      
          
        //计算多项式系数     
        cx = 3.0 * (cp[1].x - cp[0].x);      
        bx = 3.0 * (cp[2].x - cp[1].x) - cx;      
        ax = cp[3].x - cp[0].x - cx - bx;      
          
        cy = 3.0 * (cp[1].y - cp[0].y);      
        by = 3.0 * (cp[2].y - cp[1].y) - cy;      
        ay = cp[3].y - cp[0].y - cy - by;      
          
        //计算位于参数值t的曲线点    
        tSquared = t * t;      
        tCubed = tSquared * t;      
          
        result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;      
        result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;      
          
        return result;      
    }    

    //ComputeBezier以控制点cp所产生的曲线点,填入Point2D的阵列,必须分配足够的记忆体,其<sizeof(Point2D) numberOfPoints>    
    function ComputeBezier(cp, numberOfPoints, curve) {      
        var dt;      
        var i;      
          
        dt = 1.0 / ( numberOfPoints - 1 );      
          
        for( i = 0; i < numberOfPoints; i++)      
            curve[i] = PointOnCubicBezier( cp, i*dt );      
    }
});  







  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值