みかづきブログ その3

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

Canvas アニメーション習作 その2

前回つくったもの の焼き直しです。


Canvas アニメーション習作 - みかづきブログ その3



DEMO

See the Pen Dots by kimmy (@kimmy) on CodePen.


JavaScript

(function(win, doc) {
  function Dot(ctx) {
    this.ctx = ctx;
  }
  Dot.SIZE = {
    MAX: 30,
    DIFF: 10
  };
  Dot.prototype = {
    constructor: Dot,
    draw: function(x, y, size) {
      var ctx = this.ctx;

      ctx.save();
      ctx.fillStyle = "#00695C";
      ctx.beginPath();
      ctx.fillRect(x - size / 2, y - size / 2, size, size);
      ctx.globalCompositeOperation = "lighter";
      ctx.fill();
      ctx.restore();
    }
  };

  function Dots(canvas, width, height) {
    $(canvas).css({
      marginTop: -height,
      marginLeft: -width
    });
    this.ctx = canvas.getContext("2d");
    this.dot = new Dot(ctx);
    this.distance = 50;
    this.list = (function(that, width, height) {
      var list = [],
          min = (width < height) ? width : height,
          i = 0,
          length = min / that.distance - 1 | 0,
          margin = (min - (length - 1) * that.distance) / 2;
      
      for (; i < length; ++i) {
        list.push(that.distance * i + margin);
      }

      return list;
    })(this, width * 2, height * 2);
    this.length = Math.pow(this.list.length, 2);
    this.limit = this._getDistance(this.list[0], this.list[0], this.list[1], this.list[1]);
  }
  Dots.prototype = {
    constructor: Dots,
    _getDistance: function(x1, y1, x2, y2) {
      return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
    },
    _getSize: function(distance) {
      var per = distance / this.limit;

      if (per > 1) {
        per = 1;
      }

      return Dot.SIZE.MAX - Dot.SIZE.DIFF * per;
    },
    draw: function(x2, y2) {
      var ctx = this.ctx,
        dot = this.dot,
        list = this.list,
        r, x1, y1;

      for (var i = 0, length = this.length; i < length; ++i) {
        x1 = list[i % this.list.length];
        y1 = list[i / this.list.length | 0];
        r = this._getSize(this._getDistance(x1, y1, x2, y2));
        dot.draw(x1, y1, r);
      }
    },
    getRandom: function() {
      return this.list[Math.random() * this.list.length | 0];
    }
  };

  var min = (win.innerWidth < win.innerHeight) ? win.innerWidth : win.innerHeight,
      width = min / 2,
      height = min / 2,
      canvas = doc.getElementById("canvas"),
      ctx = canvas.getContext("2d"),
      dots = new Dots(canvas, width, height);

  _init();

  function _init() {
    var i = 0,
        r = 20,
        $obj;

    $obj = $({
      x : dots.getRandom(),
      y : dots.getRandom()
    });

    _draw();

    (function animate() {
      var ms = 200;

      $obj.animate({
        x: dots.getRandom(),
        y: dots.getRandom()
      }, {
        duration: ms,
        progress: _draw,
        complete: animate
      });
    })();

    function _draw() {
      _clearCanvas();
      ctx.fillStyle = "#004D40";
      ctx.fillRect(0, 0, width * 2, height * 2);
      dots.draw($obj[0].x, $obj[0].y);
    }
  }

  function _clearCanvas() {
    canvas.width = width * 2;
    canvas.height = height * 2;
  }
})(this, document);

汎用性を意識してコーディングすると、時間がないときに大変助かります。
過去の自分に感謝ですね。