网上下载html5+js做成的烟火程序。有一个地方不太懂,向大家提问。
bgColor = '#111'; gravity = 0.03; particleColor = '#f73'; //创建canvas对象,获取2d渲染 canvas = document.querySelector('canvas'); ctx = canvas.getContext('2d'); //调整窗体大小的时候触发 (onresize = function(){ width = canvas.width = canvas.clientWidth; height = canvas.height = canvas.clientHeight; o = {x:Math.floor(width/2),y:Math.floor(height/2)}; edge = {top:-o.y,right:width-o.x,bottom:height-o.y,left:-o.x} })(); particles = {}; newParticle = (function(){ var nextIndex = 0; return function(x,y,r,o,c,xv,yv,rv,ov){ particles[++nextIndex] = { index: nextIndex, x: x, y: y, r: r, o: o, c: c, xv: xv, yv: yv, rv: rv, ov: ov }; }; })(); //创建一个新的火球 fireballs = {}; newFireball = (function(){ var nextIndex = 0; return function(x,y,xv,yv,life){ fireballs[++nextIndex] = { index: nextIndex, x: x, y: y, xv: xv, yv: yv, life: life }; }; })(); //移动鼠标时候触发,获取鼠标的移动的坐标,并计算出与pos1位置移动的距离 mouse = {x:0,y:0,d:0}; onmousemove = function(e){ mouse.x = e.clientX-o.x; mouse.y = e.clientY-o.y; var dx = mouse.x - pos1.x, dy = mouse.y - pos1.y; mouse.d = Math.sqrt(dx*dx+dy*dy); // console.log('移动触发,坐标是:'); // console.log(mouse); // console.log(time); // console.log(fireballs); }; //鼠标按下时候触发,第一次位置的坐标 charging = false; pos1 = {x:0,y:0}; showInstructions = true; onmousedown = function(e){ pos1.x = mouse.x; pos1.y = mouse.y; charging = true; showInstructions = false; }; //鼠标键抬起的时候触发,将创建一个新的火球 onmouseup = function(){ if(charging){ newFireball( mouse.x, mouse.y, (pos1.x-mouse.x)*0.03, (pos1.y-mouse.y)*0.03, 600 ); charging = false; } }; time = 0; times=0; requestAnimationFrame(loop = function(){ //console.log(++times); // context.setTransform(a,b,c,d,e,f); // 将当前转换重置为单位矩阵 // a 水平缩放绘图。b 水平倾斜绘图。c 垂直倾斜绘图。d 垂直缩放绘图。e 水平移动绘图。f 垂直移动绘图。 ctx.setTransform(1,0,0,1,0,0); //默认。在目标图像上显示源图像。 //源图像 = 您打算放置到画布上的绘图。 //目标图像 = 您已经放置在画布上的绘图。 ctx.globalCompositeOperation = 'source-over'; //设置或返回绘图的当前 alpha 或透明值。 ctx.globalAlpha = 1; //设置背景颜色,#111 ctx.fillStyle = bgColor; //设置矩形的大小,与上面窗体调整时候已经设置 ctx.fillRect(0,0,width,height); //重新映射画布上的 (0,0) 位置。将上面窗体调整时候设置中心位置为0,0 x,y轴 ctx.translate(o.x,o.y); //鼠标按下时候为charging为true,画出鼠标按下与抬起之间的一条直线 if(charging){ //定义色值 var c = Math.floor(30+mouse.d/2); //设置画笔的颜色 ctx.strokeStyle = 'rgba('+c+','+c+','+c+',1)'; //线的宽度 ctx.lineWidth = 4; //起始一条路径,或重置当前路径。 ctx.beginPath(); //把路径移动到画布中的指定点,不创建线条。 鼠标按下的位置 ctx.moveTo(pos1.x,pos1.y); //添加一个新点,然后在画布中创建从该点到最后指定点的线条 ctx.lineTo(mouse.x,mouse.y); //设置或返回线条的结束端点样式 //butt 默认。向线条的每个末端添加平直的边缘。 //round 向线条的每个末端添加圆形线帽。 //square 向线条的每个末端添加正方形线帽。 ctx.lineCap = 'round'; //绘制已定义的路径。 ctx.stroke(); } //鼠标没有点击的时候自动释放烟火 if(showInstructions){ pos1.x = -70; pos1.y = -35; //x,y为终点坐标 if(time<10){ var x = -70, y = -35, r = 30-time*2,//这个参数表示圆的从30到10渐变的过程 a = time/10; }else if(time<80){ //自动划线time记数 var x = (time-10)*2-70, y = (time-10)-35, r = 10, a = 1; }else if(time<90){ var x = 70, y = 35, r = 10+(time-80)*2, a = 1-(time-80)/10; }else if(time<140){ var x = 70, y = 35, r = 30, a = 0; } var dx = pos1.x-x, dy = pos1.y-y, d = Math.sqrt(dx*dx+dy*dy); //每次请求的time值在不断的变化,这里是自动划线的功能,time的值在10到80之间划线,准备发射烟火 //这里是坐标(-70,-35)到(70,35)划线的过程,time每次变化都要跟着划线 if(time<80&&time>10){ ctx.globalCompositeOperation = 'source-over'; ctx.globalAlpha = 1; var c = Math.floor(30+d/2); ctx.strokeStyle = 'rgba('+c+','+c+','+c+',1)'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(pos1.x,pos1.y); ctx.lineTo(x,y); ctx.lineCap = 'round'; ctx.stroke(); } //当time小于140的时候画园 if(time<140){ ctx.globalCompositeOperation = 'source-over'; ctx.globalAlpha = a; ctx.beginPath(); //画圆,参数分别是x,y为坐标,r半径,0表示角度,PI*2 ctx.arc(x,y,r,0,Math.PI*2); ctx.lineWidth = 2; ctx.strokeStyle = '#aaa'; ctx.stroke(); } //当time=80的时候制造一个火球 if(time==80){ newFireball( x, y, dx*0.03, dy*0.03, 240 ); } //0-179自增 time = (time+1)%180; } //前面我看代码写的注释,不知道对不对,这里到后面就不明白,代码的原理,恳请大神解释下。 ctx.globalCompositeOperation = 'lighter'; for(var i in particles){ var p = particles[i]; ctx.beginPath(); ctx.arc(p.x,p.y,p.r,0,Math.PI*2); ctx.globalAlpha = p.o; ctx.fillStyle = p.c; ctx.fill(); } for(var i in particles){ var p = particles[i]; p.x += p.xv; p.y += p.yv; p.r += p.rv; p.o += p.ov; if(p.r<0)delete particles[p.index]; if(p.o<0)delete particles[p.index]; } for(var i in fireballs){ f = fireballs[i]; var numParticles = Math.sqrt(f.xv*f.xv+f.yv*f.yv)/5; if(numParticles<1)numParticles=1; var numParticlesInt = Math.ceil(numParticles), numParticlesDif = numParticles/numParticlesInt; for(var j=0;j<numParticlesInt;j++){ newParticle( f.x-f.xv*j/numParticlesInt, f.y-f.yv*j/numParticlesInt, 7, numParticlesDif, particleColor, Math.random()*0.6-0.3, Math.random()*0.6-0.3, -0.3, -0.05*numParticlesDif ); } f.x += f.xv; f.y += f.yv; f.yv += gravity; var boundary; if(f.y<(boundary = edge.top+7)){ f.y = boundary; f.yv *= -1; }else if(f.y>(boundary = edge.bottom-7)){ f.y = boundary; f.yv *= -1; } if(f.x>(boundary = edge.right-7)){ f.x = boundary; f.xv *= -1; }else if(f.x<(boundary = edge.left+7)){ f.x = boundary; f.xv *= -1; } if(--f.life<0)delete fireballs[f.index]; } requestAnimationFrame(loop); });
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
http://www.php100.com/html/it/focus/2014/1110/7758.html 11html5动画网址附带源码。