addEventListener(‘click’, function(e){})で、push(new Ball(x, y, r))します。ランダム関数の範囲をとる際には、return min + Math.floor(Math.random() * (max – min + 1))と書きます。また、ボールの移動は、x++, y++, バウンドは、x軸、y軸をそれぞれ-1をかけてあげます。
reference
.getBoundingClientRect():returns the size of an element and its position relative to the viewport.
setTimeout bind: http://stackoverflow.com/questions/2130241/pass-correct-this-context-to-settimeout-callback
Object.prototype: property represents the Object prototype object.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Intractive Art</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
</style>
</head>
<body>
<canvas id="mycanvas" width="500" height="250">
</canvas>
<script>
(function(){
'use strict';
var canvas;
var ctx;
var Ball;
var balls = [];
var Stage;
var stage;
canvas = document.getElementById('mycanvas');
if (!canvas || !canvas.getContext) return false;
ctx = canvas.getContext('2d');
function rand(min, max){
return min + Math.floor(Math.random() * (max - min + 1));
}
function adjustPosition(pos, r, max) {
/*if (x - r < 0) x = r;
if (y - r < 0) y = r;
if (x + r > canvas.width) x = canvas.width - r;
if (y + r > canvas.height) y = canvas.height - r;*/
if (pos - r < 0){
return r;
} else if (pos + r > max){
return max - r;
} else {
return pos;
}
}
canvas.addEventListener('click', function(e){
var x, y, r;
var rect;
/*x = rand(100, 400);
y = rand(100, 200);*/
rect = e.target.getBoundingClientRect();
x = e.clientX - rect.left;
y = e.clientY - rect.top;
r = rand(0, 100) < 20 ? rand(50, 80) : rand(10, 35);
/*if (x - r < 0) x = r;
if (y - r < 0) y = r;
if (x + r > canvas.width) x = canvas.width - r;
if (y + r > canvas.height) y = canvas.height - r;*/
x = adjustPosition(x, r, canvas.width);
y = adjustPosition(y, r, canvas.height);
balls.push(new Ball(x, y, r));
});
Ball = function(x, y, r){
this.x = x;
this.y = y;
this.r = r;
this.vx = rand(-10, 10);
this.vy = rand(-10, 10);
this.color = 'hsla(' + rand(50, 100)+ ', ' + rand(40, 80) + '%, ' + rand(50, 60) +'%, ' + Math.random() + ')';
};
/*var ball = new Ball(rand(100, 200), rand(100, 200), rand(10, 50));
ball.draw();*/
Ball.prototype.draw = function(){
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI*2);
ctx.fillStyle = this.color;
ctx.closePath();
ctx.fill();
};
Ball.prototype.move = function(){
if (this.x + this.r > canvas.width || this.x - this.r < 0){
this.vx *= -1;
}
if (this.y + this.r > canvas.height || this.y - this.r < 0){
this.vy *= -1;
}
this.x += this.vx;
this.y += this.vy;
};
Stage = function(){
this.update = function(){
var i;
this.clear();
for (i = 0; i < balls.length; i++){
balls[i].draw();
balls[i].move();
}
setTimeout(function(){
this.update();
}.bind(this), 30);
};
this.clear = function(){
ctx.fillStyle = "#ecf0f1";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
};
stage = new Stage();
stage.update();
})();
</script>
</body>
</html>