canvas实现动态小球重叠效果
前面的话
在javascript运动系列中,详细介绍了各种运动,其中就包括碰壁运动。但是,如果用canvas去实现,却是另一种思路。本文将详细介绍canvas动态小球重叠效果
静态小球
首先,生成随机半径、随机位置的50个静态小球
<buttonid="btn">按钮</button>
<canvasid="canvas"width="500"height="300"style="border:1pxsolidblack">当前浏览器不支持canvas,请更换浏览器后再试</canvas>
<script>
varcanvas=document.getElementById('canvas');
varH=300,W=500;
btn.onclick=function(){
getBalls();
}
getBalls();
functiongetBalls(){
canvas.height=H;
if(canvas.getContext){
varcxt=canvas.getContext('2d');
for(vari=0;i<50;i++){
vartempR=Math.floor(Math.random()*255);
vartempG=Math.floor(Math.random()*255);
vartempB=Math.floor(Math.random()*255);
cxt.fillStyle='rgb('+tempR+','+tempG+','+tempB+')';
vartempW=Math.floor(Math.random()*W);
vartempH=Math.floor(Math.random()*H);
vartempR=Math.floor(Math.random()*50);
cxt.beginPath();
cxt.arc(tempW,tempH,tempR,0,Math.PI*2);
cxt.fill();
}
}
}
</script>
随机运动
接着,这50个小球做随机运动,需要配合定时器更新小球的运动状态。这时,需要对上面代码进行改写
<buttonid="btn">更新</button>
<canvasid="canvas"width="500"height="300"style="border:1pxsolidblack">当前浏览器不支持canvas,请更换浏览器后再试</canvas>
<script>
btn.onclick=function(){history.go();}
varcanvas=document.getElementById('canvas');
//存储画布宽高
varH=300,W=500;
//存储小球个数
varNUM=50;
//存储小球
varballs=[];
functiongetBalls(){
if(canvas.getContext){
varcxt=canvas.getContext('2d');
for(vari=0;i<NUM;i++){
vartempR=Math.floor(Math.random()*255);
vartempG=Math.floor(Math.random()*255);
vartempB=Math.floor(Math.random()*255);
vartempColor='rgb('+tempR+','+tempG+','+tempB+')';
vartempX=Math.floor(Math.random()*W);
vartempY=Math.floor(Math.random()*H);
vartempR=Math.floor(Math.random()*30+20);
vartempBall={
x:tempX,
y:tempY,
r:tempR,
stepX:Math.floor(Math.random()*4-2),
stepY:Math.floor(Math.random()*4-2),
color:tempColor,
disX:Math.floor(Math.random()*3-1),
disY:Math.floor(Math.random()*3-1)
};
balls.push(tempBall);
}
}
}
functionupdateBalls(){
for(vari=0;i<balls.length;i++){
balls[i].stepY+=balls[i].disY;
balls[i].stepX+=balls[i].disX;
balls[i].x+=balls[i].stepX;
balls[i].y+=balls[i].stepY;
}
}
functionrenderBalls(){
//重置画布高度,达到清空画布的效果
canvas.height=H;
if(canvas.getContext){
varcxt=canvas.getContext('2d');
for(vari=0;i<balls.length;i++){
cxt.beginPath();
cxt.arc(balls[i].x,balls[i].y,balls[i].r,0,2*Math.PI);
cxt.fillStyle=balls[i].color;
cxt.closePath();
cxt.fill();
}
}
}
getBalls();
clearInterval(oTimer);
varoTimer=setInterval(function(){
//更新小球运动状态
updateBalls();
//渲染小球
renderBalls();
},50);
</script>
碰壁检测
下面,增加小球的碰壁检测功能,当小球碰壁时,变为相反方向
functionbumpTest(ele){
//左侧
if(ele.x<=ele.r){
ele.x=ele.r;
ele.stepX=-ele.stepX;
}
//右侧
if(ele.x>=W-ele.r){
ele.x=W-ele.r;
ele.stepX=-ele.stepX;
}
//上侧
if(ele.y<=ele.r){
ele.y=ele.r;
ele.stepY=-ele.stepY;
}
//下侧
if(ele.y>=H-ele.r){
ele.y=H-ele.r;
ele.stepY=-ele.stepY;
}
}
<buttonid="btn">更新</button>
<canvasid="canvas"width="500"height="300"style="border:1pxsolidblack">当前浏览器不支持canvas,请更换浏览器后再试</canvas>
<script>
btn.onclick=function(){history.go();}
varcanvas=document.getElementById('canvas');
//存储画布宽高
varH=300,W=500;
//存储小球个数
varNUM=30;
//存储小球
varballs=[];
functiongetBalls(){
if(canvas.getContext){
varcxt=canvas.getContext('2d');
for(vari=0;i<NUM;i++){
vartempR=Math.floor(Math.random()*255);
vartempG=Math.floor(Math.random()*255);
vartempB=Math.floor(Math.random()*255);
vartempColor='rgb('+tempR+','+tempG+','+tempB+')';
vartempR=Math.floor(Math.random()*30+20);
vartempX=Math.floor(Math.random()*(W-tempR)+tempR);
vartempY=Math.floor(Math.random()*(H-tempR)+tempR);
vartempBall={
x:tempX,
y:tempY,
r:tempR,
stepX:Math.floor(Math.random()*13-6),
stepY:Math.floor(Math.random()*13-6),
color:tempColor
};
balls.push(tempBall);
}
}
}
functionupdateBalls(){
for(vari=0;i<balls.length;i++){
balls[i].x+=balls[i].stepX;
balls[i].y+=balls[i].stepY;
bumpTest(balls[i]);
}
}
functionbumpTest(ele){
//左侧
if(ele.x<=ele.r){
ele.x=ele.r;
ele.stepX=-ele.stepX;
}
//右侧
if(ele.x>=W-ele.r){
ele.x=W-ele.r;
ele.stepX=-ele.stepX;
}
//上侧
if(ele.y<=ele.r){
ele.y=ele.r;
ele.stepY=-ele.stepY;
}
//下侧
if(ele.y>=H-ele.r){
ele.y=H-ele.r;
ele.stepY=-ele.stepY;
}
}
functionrenderBalls(){
//重置画布高度,达到清空画布的效果
canvas.height=H;
if(canvas.getContext){
varcxt=canvas.getContext('2d');
for(vari=0;i<balls.length;i++){
cxt.beginPath();
cxt.arc(balls[i].x,balls[i].y,balls[i].r,0,2*Math.PI);
cxt.fillStyle=balls[i].color;
cxt.closePath();
cxt.fill();
}
}
}
getBalls();
clearInterval(oTimer);
varoTimer=setInterval(function(){
//更新小球运动状态
updateBalls();
//渲染小球
renderBalls();
},50);
</script>
重叠效果
canvas的合成属性globalCompositeOperation表示后绘制的图形怎样与先绘制的图形结合,属性值是字符串,可能值如下: source-over(默认):后绘制的图形位于先绘制的图形上方 source-in:后绘制的图形与先绘制的图形重叠的部分可见,两者其他部分完全透明 source-out:后绘制的图形与先绘制的图形不重叠的部分可见,先绘制的图形完全透明 source-atop:后绘制的图形与先绘制的图形重叠的部分可见,先绘制的图形不受影响 destination-over:后绘制的图形位于先绘制的图形下方,只有之前透明像素下的部分才可见 destination-in:后绘制的图形位于先绘制的图形下方,两者不重叠的部分完全透明 destination-out:后绘制的图形擦除与先绘制的图形重叠的部分 destination-atop:后绘制的图形位于先绘制的图形下方,在两者不重叠的地方,先绘制的图形会变透明 lighter:后绘制的图形与先绘制的图形重叠部分的值相加,使该部分变亮 copy:后绘制的图形完全替代与之重叠的先绘制图形 xor:后绘制的图形与先绘制的图形重叠的部分执行"异或"操作
增加小球的重叠效果为'xor',即为最终的效果展示
<buttonid="btn">变换</button>
<canvasid="canvas"width="500"height="300"style="border:1pxsolidblack">当前浏览器不支持canvas,请更换浏览器后再试</canvas>
<script>
btn.onclick=function(){history.go();}
varcanvas=document.getElementById('canvas');
//存储画布宽高
varH=300,W=500;
//存储小球个数
varNUM=30;
//存储小球
varballs=[];
functiongetBalls(){
if(canvas.getContext){
varcxt=canvas.getContext('2d');
for(vari=0;i<NUM;i++){
vartempR=Math.floor(Math.random()*255);
vartempG=Math.floor(Math.random()*255);
vartempB=Math.floor(Math.random()*255);
vartempColor='rgb('+tempR+','+tempG+','+tempB+')';
vartempR=Math.floor(Math.random()*30+20);
vartempX=Math.floor(Math.random()*(W-tempR)+tempR);
vartempY=Math.floor(Math.random()*(H-tempR)+tempR);
vartempBall={
x:tempX,
y:tempY,
r:tempR,
stepX:Math.floor(Math.random()*21-10),
stepY:Math.floor(Math.random()*21-10),
color:tempColor
};
balls.push(tempBall);
}
}
}
functionupdateBalls(){
for(vari=0;i<balls.length;i++){
balls[i].x+=balls[i].stepX;
balls[i].y+=balls[i].stepY;
bumpTest(balls[i]);
}
}
functionbumpTest(ele){
//左侧
if(ele.x<=ele.r){
ele.x=ele.r;
ele.stepX=-ele.stepX;
}
//右侧
if(ele.x>=W-ele.r){
ele.x=W-ele.r;
ele.stepX=-ele.stepX;
}
//上侧
if(ele.y<=ele.r){
ele.y=ele.r;
ele.stepY=-ele.stepY;
}
//下侧
if(ele.y>=H-ele.r){
ele.y=H-ele.r;
ele.stepY=-ele.stepY;
}
}
functionrenderBalls(){
//重置画布高度,达到清空画布的效果
canvas.height=H;
if(canvas.getContext){
varcxt=canvas.getContext('2d');
for(vari=0;i<balls.length;i++){
cxt.beginPath();
cxt.arc(balls[i].x,balls[i].y,balls[i].r,0,2*Math.PI);
cxt.fillStyle=balls[i].color;
cxt.globalCompositeOperation='xor';
cxt.closePath();
cxt.fill();
}
}
}
getBalls();
clearInterval(oTimer);
varoTimer=setInterval(function(){
//更新小球运动状态
updateBalls();
//渲染小球
renderBalls();
},50);
</script>
源码查看
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持毛票票!