Canvasでボールをはねさせる - みかづきブログ その3
context の globalCompositeOperation を lighter に指定して、 こちらのボール の塗りつぶし色を加算で合成してみましょう。
DEMO
JavaScript
(function(win, doc, ns) { "use strict"; function _reverseX(deg) { return (180 - deg) % 360; } function _reverseY(deg) { return (360 - deg) % 360; } function Ball(obj) { var _this = this; _init(); function _init() { _this.x = obj.x; _this.y = obj.y; _this.r = obj.r; _this.v = obj.v || (Math.random() * 800 | 0); _this.deg = obj.deg % 360 || (Math.random() * 360 | 0); // 塗りつぶし色を指定できるように変更 _this.color = obj.color || "rgb(" + (Math.random() * 255 | 0) + ", " + (Math.random() * 255 | 0) + ", " + (Math.random() * 255 | 0) + ")" } } Ball.prototype = new ns.EventDispatcher(); Ball.prototype.constructor = Ball; Ball.prototype.draw = function(ctx) { var _this = this; ctx.save(); // 色を加算させる ctx.globalCompositeOperation = "lighter"; ctx.fillStyle = _this.color; ctx.beginPath(); ctx.arc(_this.x, _this.y, _this.r, 0, Math.PI * 2, false); ctx.fill(); ctx.restore(); }; Ball.prototype.appendTo = function(canvas) { this.stage = this.stage || {}; this.stage.top = 0; this.stage.bottom = canvas.height; this.stage.left = 0; this.stage.right = canvas.width; }; Ball.prototype.set = function(obj) { var _this = this; _this.x = obj.x || _this.x; _this.y = obj.y || _this.y; _this.r = obj.r || _this.r; _this.v = obj.v || _this.v; _this.deg = obj.deg % 360 || _this.deg; }; Ball.prototype.move = function(delta) { var _this = this, dx = _this.v * Math.cos(_this.deg * (Math.PI / 180)), dy = _this.v * Math.sin(_this.deg * (Math.PI / 180)), x, y; x = _this.x + dx * delta / 1000; y = _this.y + dy * delta / 1000; if (_this._isOutX(x)) { _this.set({deg: _reverseX(_this.deg)}); } else { _this.x = x; } if (_this._isOutY(y)) { _this.set({deg: _reverseY(_this.deg)}); } else { _this.y = y; } }; Ball.prototype._isOutX = function(x) { var _this = this; if (x <= _this.r || x >= _this.stage.right - _this.r) { return true; } else { return false; } }; Ball.prototype._isOutY = function(y) { var _this = this; if (y <= _this.r || y >= _this.stage.bottom - _this.r) { return true; } else { return false; } }; ns.Ball = Ball; })(this, document, App); (function(win, doc, ns) { "use strict"; var ticker = new ns.Ticker(60), balls = [ new ns.Ball({ x : 200, y : 100, r : 40 }), new ns.Ball({ x : 200, y : 100, r : 40 }), new ns.Ball({ x : 200, y : 100, r : 40 }), new ns.Ball({ x : 200, y : 100, r : 40 }), new ns.Ball({ x : 200, y : 100, r : 40 }) ], canvas = doc.getElementById("canvas"), ctx = canvas.getContext("2d"), sub = doc.createElement("canvas"), sCtx = sub.getContext("2d"), fps = doc.getElementById("fps"); setup(); function setup() { canvas.width = sub.width = win.innerWidth; canvas.height = sub.height = win.innerHeight; for (var i = 0, length = balls.length; i < length; ++i) { balls[i].appendTo(canvas); } ticker.addEventListener("tick", function(evt) { fps.innerHTML = evt.measuredFPS; update(evt.delta); draw(); }); ticker.start(); } function update(delta) { for (var i = 0, length = balls.length; i < length; ++i) { balls[i].move(delta); } } function draw() { canvas.width = win.innerWidth; canvas.height = win.innerHeight; for (var i = 0, length = balls.length; i < length; ++i) { balls[i].draw(ctx); } } })(this, document, App);