HTML5 の Canvas でしょうもないものを作った(その2)

こちら。今度は円が動きます。続編はこちらです。
canvas_sample2.html

<!DOCTYPE html>
<html lang="ja">
<title>Canvas sample 2</title>
<head>
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8">
<script type="text/javascript" src="canvas_sample2.js"></script>
<style type="text/css">
body {background-color: darkseagreen;}
canvas {background-color: white; display: block; margin-left: auto;
 margin-right: auto; margin-top: 20px;}
div.ms {text-align: center;}
</style>
</head>

<body>
<canvas id="Canvas"></canvas>
<br>
<div class="ms" style="color: blue;">クリックして下さい</div>
<form>
<div class="ms"><input type="button" value="消去" onclick="cvsClear();"></div>
</form>
</body>
</html>

canvas_sample2.js

var wd, cvs, ctx, r, timer, num;
var x = [], y = [], v = [], cl = [];
wd = 500; r = 20; num = 0;
onload = function() {
  cvs = document.getElementById("Canvas"); ctx = cvs.getContext("2d");
  cvs.height = wd; cvs.width = wd;
  ctx.globalAlpha = 0.9;
  ctx.globalCompositeOparation = "source-over";
  cvs.onclick = setBall;
  setInterval(f, 10);
}
function f() {
  if (num == 0) {return;}
  ctx.clearRect(0, 0, wd, wd);
  for(var i = 0; i < num; i++) {
    ctx.beginPath();
    ctx.fillStyle = cl[i];
    ctx.arc(x[i], y[i], r, 0, Math.PI * 2);
    ctx.fill();
    x[i] += v[i][0]; y[i] += v[i][1];
    if (x[i] >= wd - r || x[i] <= r) {v[i][0] = -v[i][0];}
    else if (y[i] >= wd -r || y[i] <= r) {v[i][1] = -v[i][1];}
  }
}
function setBall(e) {
  var x1, y1;
  x1 = e.pageX - cvs.offsetLeft; y1 = e.pageY - cvs.offsetTop;
  if (x1 <= r || x1 >= wd - r || y1 <= r || y1 >= wd - r) {return;}
  num++;
  x[num - 1] = x1; y[num - 1] = y1;
  v[num - 1] = [(Math.random() * 2 + 2) * (Math.random() - 0.5) * 2,
                (Math.random() * 2 + 2) * (Math.random() - 0.5) * 2];
  cl[num - 1] = "rgb(" + rnd() + "," + rnd() + "," + rnd() + ")";  
}
function rnd() {
  return String(Math.floor(Math.random()*256));
}
function cvsClear() {
  ctx.clearRect(0, 0, wd, wd);
  num = 0;
}

前回作ったのはこちら

追記

オブジェクト指向バージョンです。(11/3)
canvas.sample2a.js

var wd, cvs, ctx, r, timer, num;
var Circle = function () {};
var cir = [];
wd = 500; r = 20; num = 0;
onload = function() {
  cvs = document.getElementById("Canvas"); ctx = cvs.getContext("2d");
  cvs.height = wd; cvs.width = wd;
  ctx.globalAlpha = 0.9;
  ctx.globalCompositeOparation = "source-over";
  cvs.onclick = setBall;
  setInterval(f, 10);  
}
function f() {
  if (num == 0) {return;}
  ctx.clearRect(0, 0, wd, wd);
  for(var i = 0; i < num; i++) {
    ctx.beginPath();
    ctx.fillStyle = cir[i].cl;
    ctx.arc(cir[i].x, cir[i].y, r, 0, Math.PI * 2);
    ctx.fill();
    cir[i].x += cir[i].v[0]; cir[i].y += cir[i].v[1];
    if (cir[i].x >= wd - r || cir[i].x <= r) {cir[i].v[0] = -cir[i].v[0];}
    else if (cir[i].y >= wd - r || cir[i].y <= r) {cir[i].v[1] = -cir[i].v[1];}
  }
}
function setBall(e) {
  var x1, y1;
  x1 = e.pageX - cvs.offsetLeft; y1 = e.pageY - cvs.offsetTop;
  if (x1 <= r || x1 >= wd - r || y1 <= r || y1 >= wd - r) {return;}
  num++;
  cir[num - 1] = new Circle();
  cir[num - 1].x = x1; cir[num - 1].y = y1;
  cir[num - 1].v = [(Math.random() * 2 + 2) * (Math.random() - 0.5) * 2,
                (Math.random() * 2 + 2) * (Math.random() - 0.5) * 2];
  cir[num - 1].cl = "rgb(" + rnd() + "," + rnd() + "," + rnd() + ")";
}
function rnd() {
  return String(Math.floor(Math.random()*256));
}
function cvsClear() {
  ctx.clearRect(0, 0, wd, wd);
  num = 0;
}