canvas重力小球 html+css+js

举报
北极光之夜。 发表于 2021/04/13 00:39:53 2021/04/13
【摘要】 先看效果(完整代码在底部): 因为录屏软件的原因,动画看着有点迟钝,其实是动画很顺畅的~ https://space.bilibili.com/176586698 实现过程(可一步一步实现): 1.定义标签与基本css样式: <h1>北极光之夜。</h1> <canvas id="canvas"></canvas> 12 #canvas{ p...

先看效果(完整代码在底部):

因为录屏软件的原因,动画看着有点迟钝,其实是动画很顺畅的~

https://space.bilibili.com/176586698

实现过程(可一步一步实现):

1.定义标签与基本css样式:

 <h1>北极光之夜。</h1> <canvas id="canvas"></canvas>

  
  
 
 
  • 1
  • 2
#canvas{ position: fixed; top: 0; left: 0; /*  filter: contrast(30); */ }

  
  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

主要是canvas重力小球部分,h1标题文字等的css部分就不细写了,看源码即可。

2.开始js部分实现,先获取画布:

 var canvas = document.querySelector("#canvas"); var ctx = canvas.getContext("2d");

  
  
 
 
  • 1
  • 2

3. 定义变量(看注释):

// w为画布宽 ,h为画布高 var w=0,h=0; // 存放小球颜色数组,给点好看的颜色 ╭(●`∀´●)╯ var colour = ["#00BFFF","#00FFFF","#3CB371","#FFFF00","#FF8C00","#7B68EE"]; // 存放每个小球的基本信息,位置半径等等... var arr = []; // 小球数量 var num = 66;

  
  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4.画布自适应屏幕大小函数,这个直接复制便可,以后做画布背景都可以用:

 window.onresize=resizeCanvas; function resizeCanvas(){ w=canvas.width = window.innerWidth; h=canvas.height = window.innerHeight; // 窗口大小改变时,arr数组重新初始化 arr.length = 0; chushi(); } resizeCanvas(); 

  
  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5. 定义一个函数后面用,作用是随机返回mix与max间的一个值,也直接复制:

 function getRandomArbitrary(min, max) { return Math.random() * (max - min) + min; }  

  
  
 
 
  • 1
  • 2
  • 3

Math.random() 返回0到1之间的数。

6. arr数组初始化,每个小球的初始信息:

 function chushi(){ for(let i=0;i<num;i++){ arr.push({ // x为在画布水平方向位置 x:getRandomArbitrary(15,w-15), // y为在画布垂直方向位置 y:getRandomArbitrary(-h/2,h/2), // 小球半径 r:getRandomArbitrary(5,15), //  小球水平方向移动距离大小 dx:getRandomArbitrary(-3,3), //  小球垂直方向移动距离大小 dy:0.5, // 随机颜色 color: colour[parseInt(Math.random() * (colour.length-1))] }) } } 
  
  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

parseInt()返回整数。

7.绘制画布每一帧小球 ≖‿≖✧:

function draw(){ for(let i=0;i<arr.length;i++){ let circle = arr[i]; // 开始绘制 ctx.beginPath(); // 颜色 ctx.fillStyle = circle.color; // 画圆 ctx.arc(circle.x,circle.y,circle.r,0,Math.PI*2,false); // 定义阴影  ctx.shadowOffsetx=0; ctx.shadowOffsetY=0; ctx.shadowBlur= 20; ctx.shadowColor = circle.color; // 填充 ctx.fill(); // 结束绘制 ctx.closePath(); } }

  
  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

8. 更新,小球信息要进行的变化:

function updates(){ // 循环数组 for(let i=0;i<arr.length;i++){ // 如果小球垂直位置+半径+dy+0.3 将要大于屏幕高度,就是小球要超出屏幕底部时 if(arr[i].y + arr[i].r + arr[i].dy + 0.3>=h){ // 垂直移动距离大小变负数,这样小球会往反方向移动 arr[i].dy = -arr[i].dy; // 同时垂直移动距离大小×0.9,逐渐变小,不能一直动个不停 arr[i].dy *= 0.9; // 水平方向同上 arr[i].dx *= 0.9; }else{ // 垂直移动距离大小+0.3,这样可以有加速度效果,0.3是我觉得合适,也可以其它 arr[i].dy += 0.3; } // 如果小球水平位置+半径+dx 将要大于屏幕宽度,就是小球要超出屏幕左右侧部时  if(arr[i].x + arr[i].r + arr[i].dx > w ||  arr[i].x - arr[i].r  <=0){ // 水平移动距离大小变负数,这样小球会往反方向移动 arr[i].dx = -arr[i].dx; } //小球位置改变 arr[i].x += arr[i].dx; arr[i].y += 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
  • 24
  • 25
  • 26
  • 27

9.设置动画:

// arr初始化
 chushi(); setInterval(function(){ ctx.clearRect(0, 0, w , h); //绘制 draw(); //更新 updates(); },10) 

  
  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

ctx.clearRect():清除画布。

10.给body绑定点击事件,鼠标点击窗口某一位置后小球上升一段距离:

var body =document.querySelector("#body"); body.addEventListener('click',function(event){ for(let i=0;i<arr.length;i++){ // 如果arr[i].y - arr[i].r 还大于0,0就是屏幕顶部 if(arr[i].y - arr[i].r>=0){ // dy给一个随机值 arr[i].dy = getRandomArbitrary(-10,-5); // dx给一个随机值 arr[i].dx=getRandomArbitrary(-3,3); } } })

  
  
 
 
  • 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> *{ padding: 0; margin: 0; } body{ overflow: hidden; background-color: rgb(5, 7, 24); } #canvas{ position: fixed; top: 0; left: 0; /*  filter: contrast(30); */ } .yuan{ position: absolute; width: 5px; height: 5px; border: 2px solid rgb(11, 147, 211); border-radius: 50%; animation: big 1s linear; box-shadow:inset 0 0 200px rgb(11, 147, 211); } @keyframes big{ 100%{ width: 1000px; height: 1000px; box-shadow:inset 0 0 0px rgb(11, 147, 211); border: 2px solid transparent; /* background-color: rgb(11, 147, 211); */ } } h1{ position: absolute; top: 50%; left: 50%; transform: translate(-45%,-50%); font-size: 8vw; color: transparent; -webkit-background-clip: text; background-image: url(img/star.gif); filter: drop-shadow(0 0 60px rgb(0, 132, 255)); } </style>
</head>
<body id="body"> <h1>北极光之夜。</h1> <canvas id="canvas"></canvas> <script> var canvas = document.querySelector("#canvas"); var ctx = canvas.getContext("2d"); // w为画布宽 ,h为画布高 var w=0,h=0; // 存放小球颜色数组,给点好看的颜色 ╭(●`∀´●)╯ var colour = ["#00BFFF","#00FFFF","#3CB371","#FFFF00","#FF8C00","#7B68EE"]; // 存放每个小球的基本信息,位置半径等等... var arr = []; // 小球数量 var num = 66; window.onresize=resizeCanvas; function resizeCanvas(){ w=canvas.width = window.innerWidth; h=canvas.height = window.innerHeight; // 窗口大小改变时,arr数组重新初始化 arr.length = 0; chushi(); } resizeCanvas(); function getRandomArbitrary(min, max) { return Math.random() * (max - min) + min; } function chushi(){ for(let i=0;i<num;i++){ arr.push({ // x为在画布水平方向位置 x:getRandomArbitrary(15,w-15), // y为在画布垂直方向位置 y:getRandomArbitrary(-h/2,h/2), // 小球半径 r:getRandomArbitrary(5,15), //  小球水平方向移动距离大小 dx:getRandomArbitrary(-3,3), //  小球垂直方向移动距离大小 dy:0.5, // 随机颜色 color: colour[parseInt(Math.random() * (colour.length-1))] 
/* color: `rgb(${Math.random() * 255},${Math.random() * 255},${Math.random() * 255})`
 */ }) } } function draw(){ for(let i=0;i<arr.length;i++){ let circle = arr[i]; // 开始绘制 ctx.beginPath(); // 颜色 ctx.fillStyle = circle.color; // 画圆 ctx.arc(circle.x,circle.y,circle.r,0,Math.PI*2,false); // 定义阴影  ctx.shadowOffsetx=0; ctx.shadowOffsetY=0; ctx.shadowBlur= 20; ctx.shadowColor = circle.color; // 填充 ctx.fill(); // 结束绘制 ctx.closePath(); } } function updates(){ // 循环数组 for(let i=0;i<arr.length;i++){ // 如果小球垂直位置+半径+dy+0.3 将要大于屏幕高度,就是小球要超出屏幕底部时 if(arr[i].y + arr[i].r + arr[i].dy + 0.3>=h){ // 垂直移动距离大小变负数,这样小球会往反方向移动 arr[i].dy = -arr[i].dy; // 同时垂直移动距离大小×0.9,逐渐变小,不能一直动个不停 arr[i].dy *= 0.9; // 水平方向同上 arr[i].dx *= 0.9; }else{ // 垂直移动距离大小+0.3,这样可以有加速度效果,0.3是我觉得合适,也可以其它 arr[i].dy += 0.3; } // 如果小球水平位置+半径+dx 将要大于屏幕宽度,就是小球要超出屏幕左右侧部时  if(arr[i].x + arr[i].r + arr[i].dx > w ||  arr[i].x - arr[i].r  <=0){ // 水平移动距离大小变负数,这样小球会往反方向移动 arr[i].dx = -arr[i].dx; } //小球位置改变 arr[i].x += arr[i].dx; arr[i].y += arr[i].dy; } } chushi(); setInterval(function(){ ctx.clearRect(0, 0, w , h); draw(); updates(); },10) var body =document.querySelector("#body"); body.addEventListener('click',function(event){ let left = event.clientX,top = event.clientY; console.log(left,top); let yuan = document.createElement('div'); yuan.classList.add('yuan'); yuan.style.cssText = `left: ${left}px;top: ${top}px; transform: translate(-50%,-50%); ` body.appendChild(yuan); setTimeout(function(){ body.removeChild(yuan); },999); for(let i=0;i<arr.length;i++){ if(arr[i].y - arr[i].r>=0){ arr[i].dy = getRandomArbitrary(-10,-5); arr[i].dx=getRandomArbitrary(-3,3); } } }) </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
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183

其它:

物转星移,花开花落,周而复始,生生不息,但今昔已非昨日,然今日花容依旧。- - -《虫师》
在这里插入图片描述
这是我的B站账号~:https://space.bilibili.com/176586698
敲锣打鼓~
关注一波~
会有更多有意思的东西~
大概~
╭(●`∀´●)╯╰(●’◡’●)╮

文章来源: blog.csdn.net,作者:北极光之夜。,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/luo1831251387/article/details/115580798

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。