动态背景-粒子模型

这里写图片描述
最终效果如上图所示

项目需要做一个动态背景。最开始采用轮播背景图的方式进行实现个人觉得没啥意义,二版采用js动态生成不规则图形美工觉得不好看,三版采用生成运动的物体也是最终版的前生。

使用canvas进行实现,引用jquery外部链接。

使用css,主要就定义一下canvas的背景色

*{margin: 0;padding:0;}
html,body{height:100%;width:100%;}
canvas{display: block;}
#myCanvas{background:#001022;} 
#myButtons{bottom:20px;left:20px;position:absolute;}
#myButtons button{padding:15px;}

html代码部分,div模块的内容主要用于调试,在使用时不用包含该模块。直接用canvas就可以,注意id需要与js中保持一致,canvas的宽度与高度在js的resize方法中会重写。

<canvas id="myCanvas" width="500" height="500"></canvas>

<!--控制模块-->
<div id="myButtons">
    <button id="refreshBtn">刷新</button>
    <button id="acceleBtn">加速</button>
    <button id="startAnimation">Start</button>
    <button id="stopAnimation">Stop</button>
</div>

下面是控制模块js代码,这段代码不是主要的你可以忽略不计。

    /*控制模块*/
    $("#refreshBtn").click(function(event) {myGetAsteroid()});//刷新
    $("#acceleBtn").click(function(event) {animate()});//加速
    var playAnimation = true;
    var startButton = $('#startAnimation');
    var stopButton = $('#stopAnimation');
    startButton.hide();
    startButton.click(function() {
        $(this).hide();
        stopButton.show();
        playAnimation=true;
        animate();
    });
    stopButton.click(function(){
        $(this).hide();
        startButton.show();
        playAnimation=false;
    });

定义canvas与宽高度,当窗口大小发生变化是需要更新画布大小以免物体元素移动到边界之外。

    var canvas=$('#myCanvas');
    var context=canvas.get(0).getContext("2d");
    var canvasWidth = canvas.width();
    var canvasHeight= canvas.height();

    /*更新画布大小*/
    $(window).resize(resizeCanvas);
    function resizeCanvas(){
        canvas.attr("width",$(window).get(0).innerWidth);
        canvas.attr("height",$(window).get(0).innerHeight);
        canvasWidth=canvas.width();
        canvasHeight=canvas.height();
    }

定义物体属性

    var Asteroid = function(x,y,radius,iscolor,vx,vy,ax,ay){
        this.x=x;
        this.y=y;
        this.radius=radius;//大小
        this.iscolor=iscolor;//颜色

        this.vx=vx;//x轴速度
        this.vy=vy;//y轴速度
        this.ax=ax;//x轴加速度
        this.ay=ay;//y轴加速度
    }

创建物体实体

    var asteroids = new Array();
    var getAsteroid = function() {
        for (var i = 0; i < 100; i++) {//循环需要创个的物体数量
            var x=20+(Math.random()*(canvasWidth-40));
            var y=20+(Math.random()*(canvasHeight-40));
            var radius=2+Math.random()*10;
            var iscolor='rgba('+parseInt(Math.random()*255)+','+parseInt(Math.random()*255)+','+parseInt(Math.random()*255)+',0.54)';
            var vx=Math.random()*4-2;
            var vy=Math.random()*4-2;
            var ax=Math.random()*0.2-0.1;
            var ay=Math.random()*0.2-0.1;
            asteroids.push(new Asteroid(x,y,radius,iscolor,vx,vy,ax,ay));
        };
    }

重构物体实体,此方法只为控制模块服务,在使用时可抛弃该方法。

    var myGetAsteroid = function () {
        for (var i = 0; i < asteroids.length; i++) {
            asteroids[i].x=20+(Math.random()*(canvasWidth-40));
            asteroids[i].y=20+(Math.random()*(canvasHeight-40));
            asteroids[i].radius=2+Math.random()*10;
            asteroids[i].iscolor='rgba('+parseInt(Math.random()*255)+','+parseInt(Math.random()*255)+','+parseInt(Math.random()*255)+',0.54)';
            asteroids[i].vx=Math.random()*4-2;
            asteroids[i].vy=Math.random()*4-2;
            asteroids[i].ax=Math.random()*0.2-0.1;
            asteroids[i].ay=Math.random()*0.2-0.1;
        }
    }

更新画布

    function animate(){
        context.clearRect(0,0,canvasWidth,canvasHeight);
        var asteroidsLength = asteroids.length;
        for (var i = 0; i < asteroidsLength; i++) {
            var tmpAsteroid = asteroids[i];

            /*设置边界,防止物体运行到画布之外*/
            if(tmpAsteroid.x - tmpAsteroid.radius < 0){
                tmpAsteroid.x = tmpAsteroid.radius;
                tmpAsteroid.vx *=-1;
                tmpAsteroid.ax *=-1;
            }else if(tmpAsteroid.x + tmpAsteroid.radius > canvasWidth){
                tmpAsteroid.x = canvasWidth - tmpAsteroid.radius;
                tmpAsteroid.vx *=-1;
                tmpAsteroid.ax *=-1;
            }
            if(tmpAsteroid.y - tmpAsteroid.radius < 0){
                tmpAsteroid.y = tmpAsteroid.radius;
                tmpAsteroid.vy *=-1;
                tmpAsteroid.ay *=-1;
            }else if(tmpAsteroid.y + tmpAsteroid.radius > canvasHeight){
                tmpAsteroid.y = canvasHeight - tmpAsteroid.radius;
                tmpAsteroid.vy *=-1;
                tmpAsteroid.ay *=-1;
            }

            /*限制物体最大移动速度*/
            if(Math.abs(tmpAsteroid.vx)<10){
                tmpAsteroid.vx+=tmpAsteroid.ax
            }
            if(Math.abs(tmpAsteroid.vy)<10){
                tmpAsteroid.vy+=tmpAsteroid.ay
            }

            /*摩擦力*/
            if(Math.abs(tmpAsteroid.vx)>0.1){
                tmpAsteroid.vx*=0.9;
            }else{
                tmpAsteroid.vx*=0.1;
            }
            if(Math.abs(tmpAsteroid.vy)>0.1){
                tmpAsteroid.vy*=0.9;
            }else{
                tmpAsteroid.vy*=0.1;
            }


            context.beginPath();
            for (var j = asteroidsLength-1; j > 0; j--) {
                var p2 = asteroids[j];
                var a = tmpAsteroid.x - p2.x
                var b = tmpAsteroid.y - p2.y
                var dist = Math.sqrt((a * a) + (b * b)).toFixed(2);             
                if (dist < 100) {
                    context.moveTo(tmpAsteroid.x + tmpAsteroid.vx, tmpAsteroid.y + tmpAsteroid.vy);
                    context.lineTo(p2.x + p2.vx, p2.y + p2.vy);
                }
            }           
            context.stroke();
            context.strokeStyle = 'rgba(204,204,204,0.5)';
            context.closePath();




            var tx = tmpAsteroid.x+=tmpAsteroid.vx;
            var ty = tmpAsteroid.y+=tmpAsteroid.vy;
            var tr = tmpAsteroid.radius;
            context.beginPath();
            context.fillStyle = tmpAsteroid.iscolor;            
            context.arc(tx,ty,tr,0,Math.PI*2,false);
            context.closePath();
            context.fill();

        }
        if(playAnimation){
            requestAnimationFrame(animate);
        }
    }

代码文件
http://download.csdn.net/detail/u012793146/9483578

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值