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>
源码查看
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持毛票票!