按钮
当前位置:首页 > 日记 > 正文

canvas实现动态小球重叠效果

canvas实现动态小球重叠效果

前面的话

在javascript运动系列中,详细介绍了各种运动,其中就包括碰壁运动。但是,如果用canvas去实现,却是另一种思路。本文将详细介绍canvas动态小球重叠效果

静态小球

首先,生成随机半径、随机位置的50个静态小球

<button id="btn">按钮</button><canvas id="canvas" width="500" height="300" style="border:1px solid black">当前浏览器不支持canvas,请更换浏览器后再试</canvas><script>var canvas = document.getElementById('canvas');var H=300,W=500;btn.onclick = function(){ getBalls();}getBalls();function getBalls(){ canvas.height = H; if(canvas.getContext){ var cxt = canvas.getContext('2d'); for(var i = 0; i < 50; i++){ var tempR = Math.floor(Math.random()*255); var tempG = Math.floor(Math.random()*255); var tempB = Math.floor(Math.random()*255); cxt.fillStyle = 'rgb(' + tempR + ',' + tempG + ',' + tempB + ')'; var tempW = Math.floor(Math.random()*W); var tempH = Math.floor(Math.random()*H); var tempR = Math.floor(Math.random()*50); cxt.beginPath(); cxt.arc(tempW,tempH,tempR,0,Math.PI*2); cxt.fill(); } } }</script>

随机运动

接着,这50个小球做随机运动,需要配合定时器更新小球的运动状态。这时,需要对上面代码进行改写

<button id="btn">更新</button><canvas id="canvas" width="500" height="300" style="border:1px solid black">当前浏览器不支持canvas,请更换浏览器后再试</canvas><script>btn.onclick = function(){history.go();}var canvas = document.getElementById('canvas');//存储画布宽高var H=300,W=500;//存储小球个数var NUM = 50;//存储小球var balls = [];function getBalls(){ if(canvas.getContext){ var cxt = canvas.getContext('2d'); for(var i = 0; i < NUM; i++){ var tempR = Math.floor(Math.random()*255); var tempG = Math.floor(Math.random()*255); var tempB = Math.floor(Math.random()*255); var tempColor = 'rgb(' + tempR + ',' + tempG + ',' + tempB + ')'; var tempX = Math.floor(Math.random()*W); var tempY = Math.floor(Math.random()*H); var tempR = Math.floor(Math.random()*30+20); var tempBall = { 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); } } }function updateBalls(){ for(var i = 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;  }}function renderBalls(){ //重置画布高度,达到清空画布的效果 canvas.height = H;  if(canvas.getContext){ var cxt = canvas.getContext('2d'); for(var i = 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);var oTimer = setInterval(function(){ //更新小球运动状态 updateBalls(); //渲染小球 renderBalls();},50);</script>

碰壁检测

下面,增加小球的碰壁检测功能,当小球碰壁时,变为相反方向

function bumpTest(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; }}
<button id="btn">更新</button><canvas id="canvas" width="500" height="300" style="border:1px solid black">当前浏览器不支持canvas,请更换浏览器后再试</canvas><script>btn.onclick = function(){history.go();}var canvas = document.getElementById('canvas');//存储画布宽高var H=300,W=500;//存储小球个数var NUM = 30;//存储小球var balls = [];function getBalls(){ if(canvas.getContext){ var cxt = canvas.getContext('2d'); for(var i = 0; i < NUM; i++){ var tempR = Math.floor(Math.random()*255); var tempG = Math.floor(Math.random()*255); var tempB = Math.floor(Math.random()*255); var tempColor = 'rgb(' + tempR + ',' + tempG + ',' + tempB + ')'; var tempR = Math.floor(Math.random()*30+20); var tempX = Math.floor(Math.random()*(W-tempR) + tempR); var tempY = Math.floor(Math.random()*(H-tempR) + tempR);  var tempBall = { 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); } } }function updateBalls(){ for(var i = 0; i < balls.length; i++){ balls[i].x += balls[i].stepX; balls[i].y += balls[i].stepY;  bumpTest(balls[i]); }}function bumpTest(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; }}function renderBalls(){ //重置画布高度,达到清空画布的效果 canvas.height = H;  if(canvas.getContext){ var cxt = canvas.getContext('2d'); for(var i = 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);var oTimer = 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',即为最终的效果展示

<button id="btn">变换</button><canvas id="canvas" width="500" height="300" style="border:1px solid black">当前浏览器不支持canvas,请更换浏览器后再试</canvas><script>btn.onclick = function(){history.go();}var canvas = document.getElementById('canvas');//存储画布宽高var H=300,W=500;//存储小球个数var NUM = 30;//存储小球var balls = [];function getBalls(){ if(canvas.getContext){ var cxt = canvas.getContext('2d'); for(var i = 0; i < NUM; i++){ var tempR = Math.floor(Math.random()*255); var tempG = Math.floor(Math.random()*255); var tempB = Math.floor(Math.random()*255); var tempColor = 'rgb(' + tempR + ',' + tempG + ',' + tempB + ')'; var tempR = Math.floor(Math.random()*30+20); var tempX = Math.floor(Math.random()*(W-tempR) + tempR); var tempY = Math.floor(Math.random()*(H-tempR) + tempR);  var tempBall = { 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); } } }function updateBalls(){ for(var i = 0; i < balls.length; i++){ balls[i].x += balls[i].stepX; balls[i].y += balls[i].stepY;  bumpTest(balls[i]); }}function bumpTest(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; }}function renderBalls(){ //重置画布高度,达到清空画布的效果 canvas.height = H;  if(canvas.getContext){ var cxt = canvas.getContext('2d'); for(var i = 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);var oTimer = setInterval(function(){ //更新小球运动状态 updateBalls(); //渲染小球 renderBalls();},50);</script>

源码查看

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!

相关文章

react-router JS 控制路由跳转实例

react-router JS 控制路由跳转实例

路由,控制,跳转,实例,电脑软件,Link组件用于正常的用户点击跳转,但是有时还需要表单跳转、点击按钮跳转等操作。这些情况怎么跟React Router对接呢?下面是一个表单。<form onSubmit={this.handleSubmit}> <input type="text" placeholder=…

excel倒数函数的使用教程excel倒数

excel倒数函数的使用教程excel倒数

函数,使用教程,倒数,电脑软件,excel,  在Excel中,很多情况下需要进行倒数、正数的排列,这时需要用到RANK这一函数进行排序,下面是小编整理的excel倒数函数的使用教程以供大家阅读。希望对你有帮助!excel倒数函数的使用教程示例1:正排名excel倒…

利用javascript实现的三种放大镜效

利用javascript实现的三种放大镜效

三种,源码,实例,效果,电脑软件,本文实现的是一款简单的放大镜效果,有三种不同的样式,支持移动端;大家可以直接下载源码进行学习参考,下面来一起学习学习吧。实现效果如下效果一效果二效果三调用代码如下//前面是ID或者Class,后面有init里面参数…

JS实现的模仿QQ头像资料卡显示与隐

JS实现的模仿QQ头像资料卡显示与隐

显示,头像,效果,资料卡,电脑软件,本文实例讲述了JS实现的模仿QQ头像资料卡显示与隐藏效果。分享给大家供大家参考,具体如下:我们使用QQ时经常需要查看朋友的资料卡,当我们把鼠标移入头像时,资料卡显示,并且鼠标能在头像与资料卡之间能随意移动,当…

jquery精度计算代码 jquery指定精

jquery精度计算代码 jquery指定精

精度,计算,小数位,精确,代码,本文实例为大家分享了jquery指定精确小数位的具体代码,供大家参考,具体内容如下/*** 将标签的值格式化* id 标签id* min 最小值* max 最大值*/function toFloat(id,min,max){ var htmlVal = $("#"+id).html(); …

怎么找出来被隐藏了的QQ查找被隐藏

怎么找出来被隐藏了的QQ查找被隐藏

方法,查找,电脑软件,QQ,strong,  有时候明明登录了QQ,但是却找不到QQ图标在哪里,这是因为被隐藏的原因。那么怎么把QQ找出来呢?下面小编告诉你查找被隐藏的QQ方法,希望对你有所帮助!找出来被隐藏了的QQ的方法首先要登录自己的QQ账号然后查看…

如何巧用Excel公式计算个人所得税

如何巧用Excel公式计算个人所得税

计算,个人所得税,巧用,公式,电脑软件,  个人所得税的计算看起来比较复杂,似乎不用VBA宏编程而只用公式来计算是一件不可能的事。其实,Excel提供的函数公式不但可以计算个人所得税,而且还有很大的灵活。以下是小编为您带来的关于巧用Excel公…

WPS演示怎么设置自动切换幻灯片WPS

WPS演示怎么设置自动切换幻灯片WPS

方法,设置,幻灯片,演示,设置自动,  WPS演示课件是应用最广泛的多媒体教学资源,它能够有效的将文字、图形、音频、视频、动画等多种元素融合在一起;很多情况下都是点击鼠标才会切换到下一张幻灯片,这样很不好,有些场合需要自动切换,那么如何…

jQuery Chosen通用初始化

jQuery Chosen通用初始化

初始化,通用,电脑软件,jQuery,Chosen,一直在用Chosen这个js插件,其目的就是美化下拉框。github地址:https://harvesthq.github.io/chosen/no_results_text:"xxxxx"无搜索结果时显示的文本allow_single_deselect:true 是否允许取消选择disable…

jquery中$.fn和滚动效果实现的必备

jquery中$.fn和滚动效果实现的必备

知识,滚动效果,电脑软件,jquery,fn,前言图片滚动效果相信对大家来说都不陌生,烂大街的效果图如下所示,js实现代码很短,不过如果想做的话,必须掌握jquery、IIFE、setInterval等基础以及$.fn用法:jquery中$.fn用法$.fn是jquery的命名空间,如果对jq…

怎样在WPS表格中制作下拉列表

怎样在WPS表格中制作下拉列表

下拉列表,表格,电脑软件,WPS,  通过数据有效性来制作下拉列表,这样就可以不用手动输入。只需要用鼠标点击就可以选择你需要的内容输入到单元格里了哦,很方便的操作。以下是小编为您带来的关于WPS表格中制作下拉列表,希望对您有所帮助。WPS表…

微信小程序 setData的使用方法详解

微信小程序 setData的使用方法详解

使用方法,详解,程序,电脑软件,微信小,微信小程序 setData的使用方法详解最近在使用微信小程序的setData时,遇到了以下问题。如下:官网文档在使用setData()设置数组对象的某个元素的属性时,是这么使用的:Page({ data: { array: [{text: 'init …