canvas绘制碰撞球动画

碰撞球动画
  1. 画一个简单的球

    1. 通过选择器获取画布。

      var canvas = document.getElementById('canvas');var canvas = document.querySelector('#canvas')

    2. 获取屏幕宽高,设置画布宽高为屏幕宽高,背景色。当浏览器宽高变化时重新给canvas元素设置宽高。

    1
    2
    出现问题:1. 页面出现滚动条。
    2. 宽高只是页面初始宽高,改变窗口大小时,画布不能随页面宽高切换。

    解决方法:

    1. 出现滚动条是因为canvas是行内元素(display:inline-block;),行内元素有行内行间距,故当你设置画布宽高为屏幕宽高,滚出滚动条那部分即为行间距。既然是行内元素引起的,那我就将元素设置为块级元素。同时去除默认边距。

      1
      2
      3
      4
      5
      6
      7
      8
      *{
      margin: 0;
      padding: 0;
      }
      #canvas{
      background-color: red;
      display: block;
      }
    2. 给函数添加reSize方法,当改变窗口大小时,给画布重新设置大小。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      var w, h;
      var canvas = document.querySelector('canvas');
      ~~function setSize() {
      window.onresize = arguments.callee;
      w = window.innerWidth;
      h = window.innerHeight;
      canvas.width = w;
      canvas.height = h;
      }();
      //立即执行函数写法之一,
      //还有(function(){}());
      //或(function(){})();
  2. 获取画布可画区域(getContext)

    1. 设置是2d效果还是3d效果。

      var canCon = canvas.getContext('2d');

  3. 设置用什么笔和笔的颜色。

    canCon.fillStyle = 'red';

  4. 构思图形。

    1. 提笔。(beginPath)

    2. 画什么形状,图形的位置,大小。

      canCon.arc(300,100,50,0,2*Math.PI)

  5. 开始画。

    1. 确定空心还是实心(stroke或fill)。

    2. 还是绘制文字。(fillText,strokeText)

      canCon.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
33
<script>
var w, h;
var canvas = document.querySelector('canvas');
~~function setSize() {
window.onresize = arguments.callee;
w = window.innerWidth;
h = window.innerHeight;
canvas.width = w;
canvas.height = h;
}();
var canCon = canvas.getContext('2d');
var x = randomNum(0,w);
var y = 100;
setInterval(function(){
canCon.fillStyle = randomColor();
canCon.arc(x,y++,20,0,2*Math.PI)
canCon.fill();
},1000/60);

// 随机数
function randomNum(min,max){
return Math.floor(Math.random() * (max - min) + min);
}
// 随机颜色
function randomColor(){
var r,g,b,a;
r = randomNum(0,255);
g = randomNum(0,255);
b = randomNum(0,255);
a = Math.random();
return `rgba(${r},${g},${b},${a})`;
}
</script>

至此一个闪动的滚动条出现。

要出现很多球群魔乱舞现象,需要构造一个球的生成函数,里面包括初始化值,画球,还有球的移动。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
canvas{
background-color: black;
display: block;
}
</style>
</head>
<body>
<canvas></canvas>
</body>
</html>
<script>
var canvas = document.querySelector('canvas');
var w,h;
var aBubble = [];
~~function(){
window.onresize = arguments.callee;
w = window.innerWidth;
h = window.innerHeight;
canvas.width = w;
canvas.height = h;
}();
var canCon = canvas.getContext('2d');
function Bubble(){};
Bubble.prototype = {
init:function(){
this.r = random(4,6);
this.x = random(this.r,w);
this.y = random(this.r,h);
this.color = randomColor();
this.vx = random(-2,2);
this.vy = random(-1,1);
},
draw:function(){
canCon.beginPath();
canCon.fillStyle = this.color;
canCon.arc(this.x,this.y,this.r,0,Math.PI * 2);
canCon.fill();
},
move:function(){
this.x += this.vx;
this.y += this.vy;
if(this.x < this.r || this.x + this.r > w){
this.vx = -this.vx;
}
if(this.y < this.r || this.y + this.r > h){
this.vy = -this.vy;
}
this.draw();
}
}
function create(num){
for(var i = 0; i < num; i++){
var bubble = new Bubble();
bubble.init();
bubble.draw();
aBubble.push(bubble);
}
}
create(999);
setInterval(function(){
canCon.clearRect(0,0,w,h); //必须有这一句,不然贱泪横生
for(var item of aBubble){
item.move();
}
},1000/60);

// 随机数
function random(min, max){
return Math.floor(Math.random() * (max - min) + min);
}
// 随机颜色生成器
function randomColor(){
var r,g,b,a;
r = random(0,255);
g = random(0,255);
b = random(0,255);
a = Math.random();
return `rgba(${r},${g},${b},${a})`;
}
</script>

知识点:

  1. for … of …是遍历数组中的子项,for … in … 遍历下标。
  2. 创建一个数组来存放小球,用以标记已生成的小球。
文章目录
  1. 1. 碰撞球动画
|