SOURCE

console 命令行工具 X clear

                    
>
console
function getRandomColor(){
    return '#'+
    (function (color){
        return (color+='0123456789abcdef'[Math.floor(Math.random()*16)])
            && (color.length==6)?color:arguments.callee(color);
    })('');
}

function Ball(x,y,r,color){
    this.x = x||0
    this.y = y||0
    this.radius = r||12;
    this.color = color||"#6699ff"
    this.scaleX = 1;
    this.scaleY = 1;
}
Ball.prototype ={
    stroke:function(cxt){
        cxt.save()
        cxt.scale(this.scaleX,this.scaleY)
        cxt.strokeStyle=this.color
        cxt.beginPath();
        cxt.arc(this.x,this.y,this.radius,0,360*Math.PI/180,false);
        cxt.closePath();
        cxt.stroke()
        cxt.restore()
    },
    fill:function(cxt){
        cxt.save()
        cxt.translate(this.x,this.y)
        cxt.rotate(this.rotation)
        cxt.fillStyle=this.color
        cxt.scale(this.scaleX,this.scaleY)
        cxt.fillStyle=this.color
        cxt.beginPath();
        cxt.arc(0,0,this.radius,0,360*Math.PI/180,false);
        cxt.closePath();
        cxt.fill()
        cxt.restore()
    },
    getRect:function(){
        var rect = {
            x:this.x-this.radius,
            y:this.y-this.radius,
            width:this.radius*2,
            height:this.radius*2
        }
        return rect;
    } 
}

function checkRect(rectA,rectB){
    return !(rectA.x+rectA.width<rectB.x ||
        rectB.x+rectB.width<rectA.x ||
        rectA.y+rectA.height<rectB.y ||
        rectB.y+rectB.height<rectA.y);
}

var c = document.getElementById("canvas");
var cxt = c.getContext("2d");
var txt = document.getElementById('txt')

function normal(){
    cxt.clearRect(0,0,c.width,c.height);
    var ballA =  new Ball(c.width/2,c.height/2,30)
    var rectA = ballA.getRect()
    var mouse = {x:0,y:0}
    c.onmousemove = function(ev){
        var e = ev||event;
        mouse.x = e.layerX;
        mouse.y = e.layerY;     
    };
    (function frame(){
        window.requestAnimationFrame(frame);
        cxt.clearRect(0,0,c.width,c.height);
        ballA.fill(cxt);
        cxt.strokeRect(rectA.x,rectA.y,rectA.width,rectA.height)
        var ballB =  new Ball(mouse.x,mouse.y,30)
        var rectB = ballB.getRect()
        ballB.fill(cxt)
        cxt.strokeRect(rectB.x,rectB.y,rectB.width,rectB.height)
        if(checkRect(rectA,rectB)){
            txt.innerHTML="撞上了";
        }else{
            txt.innerHTML="没撞上";
        }
    })(); 
}



function middleFunc(){
    var balls=[];
    var n = 50;
    var gravity=0.15;
    var cn = 1;
    for(var i=0;i<n;i++){
        var ball =  new Ball(c.width/2,c.height/2,5,getRandomColor())
        ball.vx=(Math.random()*2-1)*cn;
        //ball.vx=cn;
        ball.vy=(Math.random()*2-1)*cn;
        balls.push(ball)
    }
    (function frame(){
        window.requestAnimationFrame(frame);
        cxt.clearRect(0,0,c.width,c.height);
        balls.forEach(function(ball){
            if(ball.x<-ball.radius || ball.x>c.width+ball.radius||
                ball.y<-ball.radius || ball.y>c.height+ball.radius){
                    ball.x=c.width/2;
                    ball.y=c.height/2;
                    ball.vx=(Math.random()*2-1)*cn
                    //ball.vx=Math.random()+cn
                    ball.vy=(Math.random()*2-1)*cn;
            }
            ball.fill(cxt);
            ball.x+=ball.vx;
            ball.y+=ball.vy;
            //ball.vy+=gravity;
        })
    })(); 
}

function gMiddleFunc(){
    var balls=[];
    var n = 50;
    var gravity=0.15;
    var cn = 3;
    for(var i=0;i<n;i++){
        var ball =  new Ball(c.width/2,c.height/2,5,getRandomColor())
        ball.vx=(Math.random()*2-1)*cn;
        //ball.vx=cn;
        ball.vy=(Math.random()*2-1)*cn;
        balls.push(ball)
    }
    (function frame(){
        window.requestAnimationFrame(frame);
        cxt.clearRect(0,0,c.width,c.height);
        balls.forEach(function(ball){
            if(ball.x<-ball.radius || ball.x>c.width+ball.radius||
                ball.y<-ball.radius || ball.y>c.height+ball.radius){
                    ball.x=c.width/2;
                    ball.y=c.height/2;
                    ball.vx=(Math.random()*2-1)*cn
                    //ball.vx=Math.random()+cn
                    ball.vy=(Math.random()*2-1)*cn;
            }
            ball.fill(cxt);
            ball.x+=ball.vx;
            ball.y+=ball.vy;
            ball.vy+=gravity;
        })
    })();   
}

function singleBounce(){
    var ball = new Ball(c.width/2,c.height/2)
    var vx=(Math.random()*2-1)*3;
    var vy=(Math.random()*2-1)*3;
    (function frame(){
        window.requestAnimationFrame(frame);
        cxt.clearRect(0,0,c.width,c.height);
        ball.x+=vx;
        ball.y+=vy;
        if(ball.x<ball.radius){
            ball.x=ball.radius;
            vx=-vx;
        }else if(ball.x>c.width-ball.radius){
            ball.x=c.width-ball.radius;
            vx=-vx;
        } 
        if(ball.y<ball.radius){
            ball.yx=ball.radius;
            vy=-vy;
        }else if(ball.y>c.height-ball.radius){
            ball.y=c.height-ball.radius;
            vy=-vy;
        }
        ball.fill(cxt);
    })();
}

function mutliBounce(){
    var balls=[];
    var n = 10;
    for(var i=0;i<n;i++){
        var ball =  new Ball(c.width/2,c.height/2,8,getRandomColor())
        ball.vx=(Math.random()*2-1)*3;
        ball.vy=(Math.random()*2-1)*3;
        balls.push(ball)
    }
    (function frame(){
        window.requestAnimationFrame(frame);
        cxt.clearRect(0,0,c.width,c.height);
        balls.forEach(function(ball){
            ball.x+=ball.vx;
            ball.y+=ball.vy;
            if(ball.x<ball.radius){
                ball.x=ball.radius;
                ball.vx=-ball.vx;
            }else if(ball.x>c.width-ball.radius){
                ball.x=c.width-ball.radius;
                ball.vx=-ball.vx;
            } 
            if(ball.y<ball.radius){
                ball.y=ball.radius;
                ball.vy=-ball.vy;
            }else if(ball.y>c.height-ball.radius){
                ball.y=c.height-ball.radius;
                ball.vy=-ball.vy;
            }
            ball.fill(cxt)
        })
    })();  
}

<canvas id="canvas" width="500" height="350" style="border:1px solid #000"></canvas>
<p id="txt"></p>
<div>
    <button onclick="normal()">鼠标移动判断是否发生碰撞</button>
    <button onclick="middleFunc()">中心散开效果</button>
    <button onclick="gMiddleFunc()">中心散开效果+重力</button>
    <button onclick="singleBounce()">单个回弹球</button>
    <button onclick="mutliBounce()">多个回弹球</button>
</div>