知乎背景图 canvas 效果

思路分析: 
1.创造一块画布, 
2.在画布内随机产生一些小球,小球位置,半径,颜射,大小,速度等都可以随机产生, 
3.定义画小球函数与小球移动函数, 
4.将每一个小球圆心都与其它小球链接, 
5判断每一个小球间的距离,大于一个值的时候断开连线,

创建一块画布

<body>
<canvas id="canvas" width="1500" height="1000" style="border: 1px solid red;"></canvas>
</body>

 

在script内获取

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d'); //因为是平面的,所以写2d

 

产生各种随机变量

首先定义一个产生随机数的函数,然后我们可以通过调用这个函数来产生想要的随机变量!

function rand(min, max) {
return parseInt(Math.random() * (max - min + 1) + min);
}

 

产生随机变量函数

function Round() {
            //随机大小
            this.r = rand(5, 20);
            //随机位置
            var x = rand(this.r,canvas.width - this.r);//仿制超出右边界
            this.x = x<this.r ? this.r:x;
            var y = rand(this.r,canvas.height - this.r);
            this.y = y<this.r ? this.r:y;
            //随机速度
            var speed = rand(1, 3);
            this.speedX = rand(0, 4) > 2 ? speed : -speed;
            this.speedY = rand(0, 4) > 2 ? speed : -speed;

        }

 

 

 

 

这里定义了一个Round函数,首先是随机出小球的半径,然后随机位置,其中

var x = rand(this.r,canvas.width - this.r);
  • 1
  • 1

的意思是定义一个变量x(作为小球圆心的x坐标).小球的位置取决于画布的大小,因为不能让小球超出画布,然后又要让每一个小球可以完全显示在画布内,所以给小球定一个范围,分别在画布左右两侧减掉小球的半径,这样就可以确保小球不会超出左右边界.

this.x = x<this.r ? this.r:x;
  • 1
  • 1

是给小球左边界做判断,当x的值小于半径时,就意味着小球不能完全显示,所以让x的值等于半径. 
随机速度的代码块

var speed = rand(1, 3);
this.speedX = rand(0, 4) > 2 ? speed : -speed;
this.speedY = rand(0, 4) > 2 ? speed : -speed;

 

第一行就是调用随机函数,在1~3中随机产生速度,后两行的意思是,在0~4间随机产生一个数,如果此数大于2,就给速度取负值,防止每一个小球都按照一个方向移动,

定义三个原型链,分别是画小球,移动,链接

Round.prototype.draw = function() {
                    ctx.fillStyle = 'rgba(200,200,200,0.5)';
                    ctx.beginPath();
                    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, true);
                    ctx.closePath();
                    ctx.fill();
                }

 

用canvas画球比较基础,

ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, true);

因为每次this.x, this.y, this.r的值都是随机产生,所以球的信息也不一样,

Round.prototype.move = function() {
                this.x += this.speedX/10;
                if (this.x > canvas.width  || this.x < 0) {
                    this.speedX *= -1;
                }
                this.y += this.speedY/10;
                if (this.y > canvas.height  || this.y < 0) {
                    this.speedY *= -1;
                }
            }

 

 

通过随机产生的速度来改变小球圆心的位置,从而小球跟随移动.然后做一个判断当圆心坐标大于画布宽度或小于0时,让速度取反,这样小球会改变运动轨迹,做反向运动.

Round.prototype.links = function(){
                for (var i=0;i<ballobj.length;i++) {
                    var l = Math.sqrt((ballobj[i].x - this.x)*(ballobj[i].x - this.x)+(ballobj[i].y - this.y)*(ballobj[i].y - this.y));
                    var a = 1/l *100;
                    if(l<250){
                    ctx.beginPath();
                    ctx.moveTo(this.x,this.y);
                    ctx.lineTo(ballobj[i].x,ballobj[i].y);
                    ctx.strokeStyle = 'rgba(200,200,200,'+a+')';
                    ctx.stroke();
                    ctx.closePath();
                    }
            }
            }

 

首先遍历每一个产生的小球,利用勾股定理计算出每一个小球间的距离,用于后期做连线判断,定义了一个变量a,a的作用是改变连线的透明度,这样就可以做到线越长越淡,最后断开,最后就是让小球相连接即可,

产生小球的函数

        var ballobj = [];
        function init() {
            for (var i = 0; i < 50; i++) {
                var obj = new Round();
                obj.draw();
                obj.move();
                ballobj.push(obj);
            }
        }
        init();

 

 

 

定义一个数组用于存放小球,通过循环产生50个小球,并把它们存放到数组中,

小球移动函数

function ballmove(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
            for (var i=0;i<ballobj.length;i++) {
                var ball = ballobj[i];
                ball.draw();
                ball.move();
                ball.links();
            }
            window.requestAnimationFrame(ballmove);
        }
        ballmove();

 

首先清除画布,否则会有小球的运动轨迹出现,然后通过循环数组的长度,给数组内每一个小球元素调用方法,最后用动画帧处理ballmove函数即可.

全部代码

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>

    <body>
        <canvas id="canvas" width="1500" height="1000" style="border: 1px solid red;"></canvas>
    </body>
    <script type="text/javascript">
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext('2d');

        function rand(min, max) {
            return parseInt(Math.random() * (max - min + 1) + min);
        }

        function Round() {
            //随机大小
            this.r = rand(5, 20);
            //随机位置
            var x = rand(0,canvas.width - this.r);//仿制超出右边界
            this.x = x<this.r ? this.r:x;
            var y = rand(0,canvas.height - this.r);
            this.y = y<this.r ? this.r:y;
            //随机速度
            var speed = rand(1, 3);
            this.speedX = rand(0, 4) > 2 ? speed : -speed;
            this.speedY = rand(0, 4) > 2 ? speed : -speed;

        }
        Round.prototype.draw = function() {
                    ctx.fillStyle = 'rgba(200,200,200,0.5)';
                    ctx.beginPath();
                    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, true);
                    ctx.closePath();
                    ctx.fill();
                }
            Round.prototype.links = function(){
                for (var i=0;i<ballobj.length;i++) {
//                  var ball = ballobj[i];
                    var l = Math.sqrt((ballobj[i].x - this.x)*(ballobj[i].x - this.x)+(ballobj[i].y - this.y)*(ballobj[i].y - this.y));
                    var a = 1/l *100;
                    if(l<250){
                    ctx.beginPath();
                    ctx.moveTo(this.x,this.y);
                    ctx.lineTo(ballobj[i].x,ballobj[i].y);
                    ctx.strokeStyle = 'rgba(200,200,200,'+a+')';
                    ctx.stroke();
                    ctx.closePath();
                    }
            }
            }
            Round.prototype.move = function() {
                this.x += this.speedX/10;
                if (this.x > canvas.width  || this.x < 0) {
                    this.speedX *= -1;
                }
                this.y += this.speedY/10;
                if (this.y > canvas.height  || this.y < 0) {
                    this.speedY *= -1;
                }
            }
        var ballobj = [];

        function init() {
            for (var i = 0; i < 50; i++) {
                var obj = new Round();
                obj.draw();
                obj.move();
                ballobj.push(obj);
            }
        }
        init();
        function ballmove(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
            for (var i=0;i<ballobj.length;i++) {
                var ball = ballobj[i];
                ball.draw();
                ball.move();
                ball.links();
            }
            window.requestAnimationFrame(ballmove);
        }
        ballmove();
    </script>

</html>
posted @ 2016-12-05 15:11  单眼皮男生  阅读(2110)  评论(0编辑  收藏  举报