canvas小球连线碰撞效果 html+css+js
【摘要】 先看效果(完整代码在底部):
canvas小球连线碰撞完整源代码 html+css+js
这是我的B站地址~热烈欢迎
实现(看注释,可一步一步跟着实现):
0:定义标签:
<h1>北极光之夜。</h1>
<canvas id="canvas"></canvas>
12
1. 定义变量:
/* 获取画布 */ var canvas =...
先看效果(完整代码在底部):
canvas小球连线碰撞完整源代码 html+css+js
这是我的B站地址~热烈欢迎
实现(看注释,可一步一步跟着实现):
0:定义标签:
<h1>北极光之夜。</h1>
<canvas id="canvas"></canvas>
- 1
- 2
1. 定义变量:
/* 获取画布 */ var canvas = document.querySelector("#canvas"); var ctx = canvas.getContext("2d"); /* 数组,存小球 */ var arr = []; /* 一共60个球 */ var num = 60; /* xZou与yZou为鼠标坐标,temp为变量,判断鼠标是否在canvas内 */ var xZou,yZou,temp;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2.绑定窗口大小发生改变事件,让canvas随时铺满浏览器可视区,直接copy用:
/* 绑定窗口大小发生改变事件,让canvas随时铺满浏览器可视区 */ window.onresize=resizeCanvas; function resizeCanvas(){ canvas.width=window.innerWidth; canvas.height=window.innerHeight; arr.length = 0; chushi(); } resizeCanvas();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
3. 初始化数组:
/* 初始化数组 */ function chushi(){ for(let i=0;i<num;i++){ arr.push({ /*指定值之间的随机数: Math.random() * (max - min) + min; */ /* 球的x轴随机坐标 */ x:10+Math.random()*(canvas.width-20), /* 球的y轴随机坐标 */ y:10+Math.random()*(canvas.height-20), /* 球的半径,可以设置随机大小,我就不设置了 */ r:10, /* 球移动距离大小 dx,dy */ dx:10*Math.random()-5, dy:10*Math.random()-5, /* 颜色,这是蓝色 */ color: "rgba(7, 156, 255,1)" }) } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
4. 绘制小球与连线:
/* 绘制小球 */ function draw(){ for(let i=0;i<num;i++){ var yuan = arr[i]; /* 绘制圆形 */ ctx.beginPath(); ctx.arc(yuan.x,yuan.y,yuan.r,0,3.14*2,false); ctx.fillStyle = yuan.color; ctx.fill(); for(let j=i;j<num;j++){ /* 绘制球与球之间连线,只有x轴与y轴都只相差150内的才连线 */ if(Math.abs(yuan.x-arr[j].x)<150&&Math.abs(yuan.y-arr[j].y)<150){ /* 绘制连线 */ ctx.beginPath(); /* ctx.globalAlpha = 0.1; */ ctx.moveTo(yuan.x,yuan.y); /* 绘制鼠标坐标与球之间连线,只有x轴与y轴都只相差150内的才连线 */ if(Math.abs(yuan.x-xZou)<150&&Math.abs(yuan.y-yZou)<150&&temp){ ctx.lineTo(xZou,yZou); } ctx.lineTo(arr[j].x,arr[j].y); ctx.closePath(); /* 设置线条颜色,越远透明度越低,用勾股定理判断距离 */ let tm = Math.sqrt(Math.abs(yuan.x-arr[j].x)*Math.abs(yuan.x-arr[j].x) + Math.abs(yuan.y-arr[j].y)*Math.abs(yuan.y-arr[j].y)) / 212; ctx.strokeStyle = `rgba(7, 156, 255,${1-tm})`; ctx.stroke(); /* ctx.fill(); */ } } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
Math.abs()返回绝对值。
Math.sqrt()返回平方根。
5. 更新小球运动:
/* 小球运动 */ function updates(){ for(let i=0;i<num;i++){ /* 更新球的坐标,鼠标坐标与球之间只有x轴与y轴都只相差150内的球才会跟着鼠标走 */ if(Math.abs(arr[i].x-xZou)<150&&Math.abs(arr[i].y-yZou)<150&&temp){ /* 离鼠标越近走越慢 */ arr[i].x += -(arr[i].x-xZou)/(10*Math.random()+20); arr[i].y += -(arr[i].y-yZou)/(10*Math.random()+20); } /* 否则球走的距离与方向为原数组里存放的 */ else{ arr[i].x += arr[i].dx; arr[i].y += arr[i].dy; } /* 当球边碰到窗口边时把原来走的距离设置为负数,这样小球会碰撞效果 */ if(arr[i].x<=arr[i].r || arr[i].x >= (canvas.width - arr[i].r) ){ arr[i].dx = -arr[i].dx; } if(arr[i].y<=arr[i].r || arr[i].y >= (canvas.height - arr[i].r) ){ arr[i].dy = -arr[i].dy; } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
6. 设置定时器:
/* 定时器,开始清除,渲染,更新 */ chushi(); setInterval(function(){ ctx.clearRect(0,0,canvas.width,canvas.height); draw(); updates(); },50)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
7. 鼠标进入离开canvas事件:
/* 鼠标进入canvas事件, */ var xZou,yZou,temp; canvas.addEventListener('mousemove',function(e){ /* 赋值 */ xZou = e.clientX; yZou = e.clientY; temp=1; }) /* 鼠标离开canvas,tmep为0,上面的跟随鼠标运动无效了 */ canvas.addEventListener('mouseout',function(e){ temp=0; })
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
完整代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{ margin: 0; padding: 0; } body{ height: 100vh; display: flex; justify-content: center; align-items: center; background-color: rgb(11, 10, 46); } h1{ font-family: 'fangsong'; position: absolute; font-size: 5em; color: rgb(17, 167, 226); transform: translateX(40px); text-shadow: 0 0 10px rgb(38, 17, 226), 0 0 20px rgb(38, 17, 226), 0 0 30px rgb(38, 17, 226); user-select: none; } </style>
</head>
<body> <h1>北极光之夜。</h1> <canvas id="canvas"></canvas> <script> /* 获取画布 */ var canvas = document.querySelector("#canvas"); var ctx = canvas.getContext("2d"); /* 数组,存小球 */ var arr = []; /* 一共60个球 */ var num = 60; /* xZou与yZou为鼠标坐标,temp为变量,判断鼠标是否在canvas内 */ var xZou,yZou,temp; /* 绑定窗口大小发生改变事件,让canvas随时铺满浏览器可视区 */ window.onresize=resizeCanvas; function resizeCanvas(){ canvas.width=window.innerWidth; canvas.height=window.innerHeight; arr.length = 0; chushi(); } resizeCanvas(); /* 初始化数组 */ function chushi(){ for(let i=0;i<num;i++){ arr.push({ /*指定值之间的随机数: Math.random() * (max - min) + min; */ /* 球的x轴随机坐标 */ x:10+Math.random()*(canvas.width-20), /* 球的y轴随机坐标 */ y:10+Math.random()*(canvas.height-20), /* 球的半径,可以设置随机大小,我就不设置了 */ r:10, /* 球移动距离大小 dx,dy */ dx:10*Math.random()-5, dy:10*Math.random()-5, /* 颜色,这是蓝色 */ color: "rgba(7, 156, 255,1)" }) } } /* 绘制小球 */ function draw(){ for(let i=0;i<num;i++){ var yuan = arr[i]; /* 绘制圆形 */ ctx.beginPath(); ctx.arc(yuan.x,yuan.y,yuan.r,0,3.14*2,false); ctx.fillStyle = yuan.color; ctx.fill(); for(let j=i;j<num;j++){ /* 绘制球与球之间连线,只有x轴与y轴都只相差150内的才连线 */ if(Math.abs(yuan.x-arr[j].x)<150&&Math.abs(yuan.y-arr[j].y)<150){ /* 绘制连线 */ ctx.beginPath(); /* ctx.globalAlpha = 0.1; */ ctx.moveTo(yuan.x,yuan.y); /* 绘制鼠标坐标与球之间连线,只有x轴与y轴都只相差150内的才连线 */ if(Math.abs(yuan.x-xZou)<150&&Math.abs(yuan.y-yZou)<150&&temp){ ctx.lineTo(xZou,yZou); } ctx.lineTo(arr[j].x,arr[j].y); ctx.closePath(); /* 设置线条颜色,越远透明度越低,用勾股定理判断距离 */ let tm = Math.sqrt(Math.abs(yuan.x-arr[j].x)*Math.abs(yuan.x-arr[j].x) + Math.abs(yuan.y-arr[j].y)*Math.abs(yuan.y-arr[j].y)) / 212; ctx.strokeStyle = `rgba(7, 156, 255,${1-tm})`; ctx.stroke(); /* ctx.fill(); */ } } } } /* 小球运动 */ function updates(){ for(let i=0;i<num;i++){ /* 更新球的坐标,鼠标坐标与球之间只有x轴与y轴都只相差150内的球才会跟着鼠标走 */ if(Math.abs(arr[i].x-xZou)<150&&Math.abs(arr[i].y-yZou)<150&&temp){ /* 离鼠标越近走越慢 */ arr[i].x += -(arr[i].x-xZou)/(10*Math.random()+20); arr[i].y += -(arr[i].y-yZou)/(10*Math.random()+20); } /* 否则球走的距离与方向为原数组里存放的 */ else{ arr[i].x += arr[i].dx; arr[i].y += arr[i].dy; } /* 当球边碰到窗口边时把原来走的距离设置为负数,这样小球会碰撞效果 */ if(arr[i].x<=arr[i].r || arr[i].x >= (canvas.width - arr[i].r) ){ arr[i].dx = -arr[i].dx; } if(arr[i].y<=arr[i].r || arr[i].y >= (canvas.height - arr[i].r) ){ arr[i].dy = -arr[i].dy; } } } /* 定时器,开始清除,渲染,更新 */ chushi(); setInterval(function(){ ctx.clearRect(0,0,canvas.width,canvas.height); draw(); updates(); },50) /* 鼠标进入canvas事件, */ var xZou,yZou,temp; canvas.addEventListener('mousemove',function(e){ /* 赋值 */ xZou = e.clientX; yZou = e.clientY; temp=1; }) /* 鼠标离开canvas,tmep为0,上面的跟随鼠标运动无效了 */ canvas.addEventListener('mouseout',function(e){ temp=0; }) </script>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
总结:
夏天到了~~
文章来源: blog.csdn.net,作者:北极光之夜。,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/luo1831251387/article/details/115187689
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)