みかづきブログ その3

3ヶ月つづけてみました。

Canvasの塗りつぶし色を加算する


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);