最终效果如上图所示
项目需要做一个动态背景。最开始采用轮播背景图的方式进行实现个人觉得没啥意义,二版采用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);
}
}