みかづきブログ その3

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

CanvasにLineを引く

Canvasに打ったPointをつないでLineにするクラスをつくってみました。
Pointを直線でつなぐdrawLineメソッドと、ベジェ曲線でつなぐdrawQuadraticCurveを実装しています。
一応今後のことを考えてEventDisatcherを継承していますが、あんまり意味が無いような気がしてきました。。。



CanvasにPointを打つ - みかづきブログ その3


JavaScript

(function(win, doc, ns) {

    "use strict";

    // ベジェ曲線を引く際にポイントをつくる必要があるので泣く泣くクラスを読み込む
    var Point = ns.Point;

    function Line(opt_point) {
        var _this = this,
            pointList = [];

        _init();

        function _init() {
            ns.EventDispatcher.call(_this);

            _this.pointList = pointList;

            if (opt_point) {
                _this.push(opt_point);
            }
        }
    }

    Line.prototype = new ns.EventDispatcher();
    Line.prototype.constructor = Line;

    Line.prototype.push = function(point) {
        var _this = this;

        _this.pointList.push(point);
    };

    Line.prototype.drawLine = function(ctx) {
        var _this     = this,
            pointList = _this.pointList,
            length    = pointList.length,
            i;

        if (!length) {
            return;
        }

        // Pointが2点以上だったらつなぐ
        if (length > 1) {
            ctx.beginPath();
            ctx.moveTo(pointList[0].x, pointList[0].y);

            for (i = 1; i < length; ++i) {
                ctx.lineTo(pointList[i].x, pointList[i].y);
            }

            ctx.stroke();
        } else {
            // Pointが1点だったらPointを打つ
            pointList[0].draw(ctx);
        }
    };

    Line.prototype.drawQuadraticCurve = function(ctx) {
        var _this              = this,
            pointList          = _this.pointList,
            length             = pointList.length,
            quadraticPointList = [],
            lastIndex          = 0,
            i;

        if (!length) {
            return;
        }

        // Pointが2点以上だったらつなぐ
        if (length > 1) {
            ctx.beginPath();
            quadraticPointList[lastIndex] = pointList[0];
            ctx.moveTo(quadraticPointList[0].x, quadraticPointList[0].y);

            for (i = 1; i < length; ++i) {
                // 中点に新しいPointを打つ
                quadraticPointList[++lastIndex] = new Point(
                    (quadraticPointList[lastIndex - 1].x + pointList[i].x) / 2,
                    (quadraticPointList[lastIndex - 1].y + pointList[i].y) / 2
                );
                quadraticPointList[++lastIndex] = (pointList[i]);

                // 中点同士をベジェ曲線でつなぐ
                ctx.quadraticCurveTo(
                    quadraticPointList[i * 2 - 2].x,
                    quadraticPointList[i * 2 - 2].y,
                    quadraticPointList[i * 2 - 1].x,
                    quadraticPointList[i * 2 - 1].y
                );
            }

            // 最後のPointまでLineをつなぐ
            ctx.lineTo(quadraticPointList[lastIndex].x, quadraticPointList[lastIndex].y);
            ctx.stroke();
        } else {
            // Pointが1点だったらPointを打つ
            pointList[lastIndex].draw(ctx);
        }
    };

    ns.Line = Line;

})(this, document, App);

つかいかた

HTML

<canvas id="canvas"></canvas>

JavaScript

(function(win, doc, ns) {

    "use strict";
    
    var canvas = doc.getElementById("canvas"),
        ctx = canvas.getContext("2d"),
        line = new ns.Line();
    
    canvas.width = win.innerWidth;
    canvas.height = win.innerHeight;
    
    line.push(new ns.Point(100, 100));
    line.push(new ns.Point(200, 100));
    line.push(new ns.Point(200, 200));
    line.push(new ns.Point(300, 200));
    line.push(new ns.Point(300, 300));
    
    ctx.save();
        ctx.strokeStyle = "rgba(255, 0, 0, 0.8)";
        line.drawLine(ctx);
    ctx.restore();
    ctx.save();
         ctx.strokeStyle = "rgba(0, 0, 255, 0.8)";
        line.drawQuadraticCurve(ctx);
    ctx.restore();

})(this, document, App);

DEMO



前回打ったPoint をつないでLineを引きました。
赤い線はdrawLineをつかって直接つないだもの、青い線はdrawQuadraticCurveをつかってベジェ曲線をつかってつないだものです。