赞
踩
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>圆形扩散</title> <style> body { overflow: hidden; background: #000; } body, html { height: 100%; width: 100%; margin: 0; padding: 0; } </style> </head> <body> <canvas id="canvas"></canvas> </body> <script type="text/javascript"> var oAnim=document.getElementById('canvas'); var context = oAnim.getContext("2d"); var radius=0 function drawCircle(){ context.beginPath(); render(radius); context.arc(50,50,radius,0,Math.PI * 2); context.closePath(); context.lineWidth=2; context.strokeStyle='rgba(250,250,50,1)'; context.stroke(); radius +=0.5;//每帧半径增加0.5 if(radius > 20){ radius=0; } } function render(x) { //默认值为source-over,覆盖原图上面,效果像z-index:999<br> var prev = context.globalCompositeOperation; //<br><br> //只显示canvas上原图像的重叠部分<br> context.globalCompositeOperation = 'destination-in'; //<br><br> //设置主canvas的绘制透明度,圆圈中间的浅黄色部分<br> context.globalAlpha = 0.95; //<br> <br> //这一步目的是将canvas上的图像变的透明<br> context.fillRect(0,0,40*x,40*x); //<br><br> //在原图像上重叠新图像<br> context.globalCompositeOperation = prev //;<br> //下面代用的drawcricle方法,圆圈覆盖在正方形上 }; //在主canvas上画新圆 setInterval(function(){ drawCircle(); },20); </script> </html>
参考:https://www.cnblogs.com/anxiaoyu/p/6672187.html
canvas 雨滴效果
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>rain</title> </head> <body> <canvas id="canvas" style="position: absolute; height: 100%; width:100%;"></canvas> <script> window.onload=main; function getRgb(r,g,b){ return "rgb("+ r+","+g+","+b+")"; } function main(){ //drop来存放溅射的雨滴 var dropList=[]; //重力因素,保持溅射的雨滴不会飞远 var gravity=0.8; //保存雨滴 var linelist=[]; var canvasEl = document.getElementById('canvas'); var ctx = canvasEl.getContext('2d'); //鼠标的开始点为 var mousePos = [0, 0]; var backgroundColor = '#000'; canvasEl.width=canvasEl.clientWidth; canvasEl.height=canvasEl.clientHeight; var speedx=0; var maxspeedx=0; //当改变浏览器窗口大小时 window.onresize=function () { canvasEl.width=canvasEl.clientWidth; canvasEl.height=canvasEl.clientHeight; } //当鼠标移动时,获取坐标 window.onmousemove=function (e) { mousePos[0]=e.clientX; mousePos[1]=e.clientY; //最大速度-1到1个屏幕 maxspeedx=(e.clientX-canvasEl.clientWidth/2)/(canvasEl.clientWidth/2); } //给单个雨滴加属性 function createLine(e){ //长度在12.5-37.5之间 var temp= 0.25*( 50+Math.random()*100); //速度在16.5-50.5之间 var myline={ speed:5.5*(Math.random()*6+3), die:false, posx:e, posy:-200, h:temp, //颜色在 color:(getRgb(Math.floor(temp*255/75),Math.floor(temp*255/75),Math.floor(temp*255/75))) }; //添加到数组中 linelist.push(myline); } update(); //生产小雨滴 function createDrop(x,y){ var mydrop={ die:false, //溅射x坐标 posx:x, //溅射的y坐标 posy:y, //随机生成一个x轴速度 vx:(Math.random()-0.5)*8, //随机生成一个y轴速度 vy:Math.random()*(-6)-3, radius:Math.random()*1.5+1 }; return mydrop; } //溅射效果 function madedrops(x,y){ //溅射的雨滴数为5-10滴 var maxi=Math.floor(Math.random()*5+5); for(var i=0;i<maxi;i++){ dropList.push(createDrop(x,y)); } } function update() { //循环遍历小雨滴,显示溅射的雨滴,移除超出范围的雨滴 if(dropList.length>0){ dropList.forEach(function (e) { //小雨滴的x轴速度=随机速度+雨滴初始速度 e.vx=e.vx+(speedx)/2; //小雨滴的新坐标 e.posx=e.posx+e.vx; //小雨滴的y轴速度=随机速度+重力 e.vy=e.vy+gravity; e.posy=e.posy+e.vy; //雨滴超出屏幕高度,则消失 if(e.posy>canvasEl.clientHeight){ e.die=true; } }); } //移除超出范围的雨滴 for(var i=dropList.length-1;i>=0;i--){ if(dropList[i].die){ dropList.splice(i,1); } } //鼠标的位置控制雨的速度 //当鼠标在中间maxspeedx为0,不倾斜,速度不加快 speedx=speedx+(maxspeedx-speedx)/50; if(Math.random()>0){ //雨滴的出生点的X轴坐标在-0.5到1.5倍的屏幕,这样雨滴倾斜的时候,最角落也会有雨滴 createLine(Math.random()*1.5*canvasEl.width -Math.random()*0.5*canvasEl.width); createLine(Math.random()*1.5*canvasEl.width -Math.random()*0.5*canvasEl.width); createLine(Math.random()*1.5*canvasEl.width -Math.random()*0.5*canvasEl.width); } //雨滴到达近地面时,近地面(1到0.8的屏幕高度) var mydeadline=canvasEl.clientHeight- Math.random()*canvasEl.clientHeight/5; //监听雨滴,雨滴距离鼠标的直线距离小于35时,两点之间的距离公式 linelist.forEach(function (e) { //雨滴距离鼠标的直线距离小于35时,两点之间的距离公式 var dis=Math.sqrt( ((e.posx+speedx*e.h)-mousePos[0])*((e.posx+speedx*e.h)-mousePos[0])+(e.posy+e.h-mousePos[1])*(e.posy+e.h-mousePos[1])); if(dis<35){ //雨滴消失,产生小雨滴 madedrops(e.posx+speedx*e.h,e.posy+e.h); e.die=true; } //当雨滴到达地面时,每个雨滴的地面不同,0.8到1个屏幕高度 //如果每个 if((e.posy+e.h)>mydeadline){ //每个雨滴都出水花太多了。给个0.9的概率 if(Math.random() > 0.9){ madedrops(e.posx+speedx*e.h,e.posy+e.h); e.die=true; } } //水滴超出屏幕高度,设置为消失 if(e.posy>=canvasEl.clientHeight){ e.die=true; }else{ e.posy=e.posy+e.speed; e.posx=e.posx+(e.speed*speedx); } }); //消失雨滴 for(var i=linelist.length-1;i>=0;i--){ if(linelist[i].die){ linelist.splice(i,1); } } //清除界面 render(); //重绘页面 window.requestAnimationFrame(update); } function render() { ctx.fillStyle = backgroundColor; ctx.fillRect(0, 0, canvasEl.width, canvasEl.height); linelist.forEach( //绘制雨滴 function (line) { ctx.strokeStyle =line.color; ctx.lineWidth=4.5; ctx.beginPath(); ctx.moveTo(line.posx,line.posy); ctx.lineTo(line.posx+speedx*line.h,line.posy+line.h); ctx.stroke(); }); ctx.lineWidth=1; ctx.strokeStyle = "#fff"; //绘制溅射雨滴 dropList.forEach(function (e) { ctx.beginPath(); ctx.arc(e.posx,e.posy,e.radius,Math.random()*Math.PI*2,1*Math.PI); ctx.stroke(); }); } } </script> </body> </html>
参考:https://www.cnblogs.com/anxiaoyu/p/6689853.html
小球碰撞
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>小球碰撞反弹</title> <style type="text/css"> #canvas1{ border: 4px dashed black; margin: 0 auto; display: block; } </style> </head> <body> <canvas id="canvas1" width="600" height="600"></canvas> </body> <script type="text/javascript"> var canvas = document.getElementById("canvas1"); var ctx = canvas.getContext("2d"); //随机函数 function randomNum (m,n) { return Math.floor(Math.random() * (n - m + 1) + m); } //创建小球类 function Ball () { //随机小球半径 this.r = randomNum(15,30); //随机颜色 this.color = 'rgb(' + randomNum(0,255) + ',' + randomNum(0,255) + ',' + randomNum(0,255) + ')'; //随机小球的位置 this.x = randomNum(this.r,canvas.width-this.r); this.y = randomNum(this.r,canvas.height-this.r); //小球速度X轴1和-1; this.speedX = randomNum(2,5) * randomNum(0,1) ? 1 : -1; this.speedY = randomNum(2,5) * randomNum(0,1) ? 1 : -1; } //小球移动 Ball.prototype.move = function () { this.x += this.speedX; this.y += this.speedY; //判断是否碰到边界 //左边界 if (this.x <= this.r) { this.x = this.r; //反弹 this.speedX *= -1; } //右边界 if (this.x >= canvas.width-this.r) { this.x = canvas.width-this.r; this.speedX *= -1; } if (this.y <= this.r) { this.y = this.r; this.speedY *= -1; } if (this.y >= canvas.height-this.r) { this.y = canvas.height-this.r; this.speedY *= -1; } } //绘制小球 Ball.prototype.drawBall = function () { ctx.beginPath(); ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false); ctx.fillStyle = this.color; ctx.fill(); } //创建小球的对象 var balls = []; for (var i = 0;i < 10;i++) { var ball = new Ball(); balls.push(ball); } //让小球移动 setInterval(function () { ctx.clearRect(0,0,canvas.width,canvas.height); for (var i = 0;i < balls.length;i++) { balls[i].move(); balls[i].drawBall(); //移动后检测小球碰撞反弹 for (j = 0;j < balls.length;j++) { //判断不是同一个球 if (balls[i] == balls[j]) { continue;//不做碰撞检测 } //碰撞检测 if (ballCrash(balls[i],balls[j])) { /* 1.物理公式动量守恒,假设每个球的质地均匀,那么小球的质量与半径有关 2.我们用1一次方的算法,实际平面球质量和r的平方有关,立体球和r的三次方有关 3.由动量守恒,m1*v1+m2*v2=m1*v1'+m2*v2' 4.机械能守恒,平方我就不写了,两个方程联立 */ var fzx=(balls[i].r - balls[j].r)*balls[i].speedX + 2*balls[j].r*balls[j].speedX; var fzx2=2*balls[i].r*balls[i].speedX+(balls[i].r - balls[j].r)*balls[j].speedX; var fzy=(balls[i].r - balls[j].r)*balls[i].speedY + 2*balls[j].r*balls[j].speedY; var fzy2=2*balls[i].r*balls[i].speedY+(balls[i].r - balls[j].r)*balls[j].speedY; var fm=balls[i].r + balls[j].r; balls[i].speedX=(fzx/fm); balls[i].speedY=(fzy/fm); balls[j].speedX=(fzx2/fm); balls[j].speedY=(fzy2/fm); } } } },1) //碰撞检测 function ballCrash (ball1,ball2) { //两个小球之间的距离 var distance = Math.sqrt(Math.pow(ball1.x - ball2.x,2) + Math.pow(ball1.y - ball2.y,2)); //两球的距离小于两个半径的和即为碰撞 if (distance == ball1.r + ball2.r) { return true;//碰撞 }else if( distance < ball1.r + ball2.r){ if(Math.pow(ball1.speedX,2)+Math.pow(ball1.speedY,2)>Math.pow(ball2.speedX,2)+Math.pow(ball2.speedY,2)){ if(ball1.speedX>0){ ball2.x=ball2.x+ball1.r + ball2.r - distance; if(ball1.speedY > 0){ ball2.y=ball2.y+ball1.r + ball2.r - distance; }else{ ball2.y=ball2.y-ball1.r - ball2.r + distance; } }else{ ball2.x=ball2.x-ball1.r - ball2.r + distance; if(ball1.speedY > 0){ ball2.y=ball2.y+ball1.r + ball2.r - distance; }else{ ball2.y=ball2.y-ball1.r - ball2.r + distance; } } }else{ if(ball2.speedX>0){ ball1.x=ball1.x+ball1.r + ball2.r - distance; if(ball2.speedY > 0){ ball1.y=ball1.y+ball1.r + ball2.r - distance; }else{ ball1.y=ball1.y-ball1.r - ball2.r + distance; } }else{ ball1.x=ball1.x-ball1.r - ball2.r + distance; if(ball2.speedY > 0){ ball1.y=ball1.y+ball1.r + ball2.r - distance; }else{ ball1.y=ball1.y-ball1.r - ball2.r + distance; } } } return true; } else{ return false;//没有碰撞 } } </script> </html>
参考https://www.cnblogs.com/anxiaoyu/p/6707836.html
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>动态进度加载小球</title> <style> #c{ margin: 0 auto; display: block; } #r{ display: block; margin: 0 auto; } #r::before{ color: black; content: attr(min); padding-right: 10px; } #r::after{ color: black; content: attr(max); padding-left: 10px; } </style> </head> <body> <canvas id="c"></canvas> <input type="range" id="r" min="0" max="100" step="1"> <script> var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var range = document.getElementById('r'); //range控件信息 var rangeValue = range.value; var nowRange = 0; //用于做一个临时的range //画布属性 var mW = canvas.width = 250; var mH = canvas.height = 250; var lineWidth = 2; //圆属性 var r = mH / 2; //圆心 var cR = r - 16 * lineWidth; //圆半径 //Sin 曲线属性 var sX = 0; var sY = mH / 2; var axisLength = mW; //轴长 var waveWidth = 0.015 ; //波浪宽度(曲线周期),数越小越宽 var waveHeight = 6; //波浪高度(波峰),数越大越高 var speed = 0.09; //波浪水平速度,数越大速度越快 var xOffset = 0; //波浪x偏移量 ctx.lineWidth = lineWidth; //画圈函数 var IsdrawCircled = false; var drawCircle = function(){ ctx.beginPath(); ctx.strokeStyle = '#1080d0'; //画外圆 ctx.arc(r, r, cR+5, 0, 2 * Math.PI); ctx.stroke(); ctx.beginPath(); //显示水部分的圆 ctx.arc(r, r, cR, 0, 2 * Math.PI); //剪裁圆形,去掉多于的水 ctx.clip(); } //画sin 曲线函数 var drawSin = function(xOffset){ ctx.save(); var points=[]; //用于存放绘制Sin曲线的点,用于封闭曲线 ctx.beginPath(); //在整个轴长上取点 for(var x = sX; x < sX + axisLength; x += 20 / axisLength){ //此处坐标(x,y)的取点,依靠公式 “振幅高*sin(x*振幅宽 + 振幅偏移量)” //y=sin(TX+x) var y = -Math.sin((sX + x) * waveWidth + xOffset); //dY是波浪的高度,-是因为水从下往上 var dY = mH * (1 - nowRange / 100 ); points.push([x, dY + y * waveHeight]); //描绘点 ctx.lineTo(x, dY + y * waveHeight); } //现在一条线从左端绘制到了右端 //封闭路径 //接着连右下端 ctx.lineTo(axisLength, mH); //左下端 ctx.lineTo(sX, mH); //曲线图的最左端 //封闭完成后,调用上面的ctx.clip(),去掉圆外面的水 ctx.lineTo(points[0][0],points[0][1]); ctx.fillStyle = '#1c86d1'; ctx.fill(); ctx.restore(); }; //写百分比文本函数 var drawText = function(){ ctx.save(); var size = 0.4*cR; ctx.font = size + 'px Microsoft Yahei'; ctx.textAlign = 'center'; ctx.fillStyle = "rgba(06, 85, 128, 0.8)"; ctx.fillText(nowRange + '%', r, r + size / 2); ctx.restore(); }; var render = function(){ ctx.clearRect(0, 0, mW, mH); //通过不断刷新来获取range的值 rangeValue = range.value; if(IsdrawCircled == false){ drawCircle(); } //如果拖动input,就安每次加减1的速度增减 if(nowRange <= rangeValue){ var tmp = 1; nowRange += tmp; } if(nowRange > rangeValue){ var tmp = 1; nowRange -= tmp; } //不停的偏移,让波浪动起来 drawSin(xOffset); drawText(); //偏移量加大 xOffset += speed; requestAnimationFrame(render); } render(); </script> </body> </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。