Fabric.jsを触ってみた

自己紹介

  • @bati11_
  • バックエンドシステムの開発・運用の仕事してます
  • 仕事で使ってる言語は
    Java 60%, Ruby 20%, PHP 15%, Scala 5%, JavaScript 0%
  • でも、JavaScript好きです

Fabric.jsとは

Canvas APIを使いやすくしてくれるJavaScriptライブラリ

Canvasに四角形を描く

Canvas API


    var canvasEl = document.getElementById('c');
    var ctx = canvasEl.getContext('2d');
    ctx.fillStyle = 'red';
    ctx.fillRect(10, 10, 20, 20);
  

Canvasに四角形を描く

Fabric.js


    var canvas = new fabric.Canvas('c');
    var rect = new fabric.Rect({
      left: 10,
      top: 10,
      fill: 'red',
      width: 20,
      height: 20
    });
    canvas.add(rect);
  

2つの四角形を描く

Canvas API


    var canvasEl = document.getElementById('c');
    var ctx = canvasEl.getContext('2d');
    ctx.fillStyle = 'red';
    ctx.fillRect(10, 10, 20, 20);
    ctx.fillStyle = 'blue';
    ctx.fillRect(30, 30, 20, 20);
  

2つの四角形を描く

Fabric.js


    var canvas = new fabric.Canvas('c');
    var redRect = new fabric.Rect({
      left: 10, top: 10, fill: 'red', width: 20, height: 20
    });
    var blueRect = new fabric.Rect({
      left: 30, top: 30, fill: 'blue', width: 20, height: 20
    });
    canvas.add(redRect);
    canvas.add(blueRect);
  

四角形の位置を変える

Canvas API


    var canvasEl = document.getElementById('c');
    var ctx = canvasEl.getContext('2d');
    ctx.fillStyle = 'red';
    ctx.fillRect(10, 10, 20, 20);

    function move() {
      ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
      ctx.fillRect(40, 40, 20, 20);
    }
    documents.getElementById('button').addEventListener('click', move);
  

四角形の位置を変える

Fabric.js


    var canvas = new fabric.Canvas('c');
    var rect = new fabric.Rect({
      left: 10, top: 10, fill: 'red', width: 20, height: 20
    });
    canvas.add(rect);

    function move() {
      rect.set({left: 40, top: 40});
      canvas.renderAll();
    }
    documents.getElementById('button').addEventListener('click', move);
  

違いは...

Canvas API

  • canvas全体を1つのオブジェクトとして操作する感じ


Fabric.js

  • canvasに描く図形をそれぞれ1つのオブジェクトとして操作する感じ

さらに...

  • インタラクティブ
    描画した図形をマウスでグリグリ動かすこともできる

Fabric.jsで描画できる図形

  • Circle
  • Ellipse
  • Line
  • Polygon
  • Polyline
  • Rect
  • Triangle
  • Path(※ SVGのpathと同じような)

他にも...

画像

画像も図形と同じように扱える。


    var canvas = new fabric.Canvas('c');
    fabric.Image.fromURL('user.png', function(img) {
      img.set({left: 20, top: 20});
      canvas.add(img);
    });
    fabric.Image.fromURL('computer.png', function(img) {
      img.set({left: 120, top: 40});
      img.filters.push(
        new fabric.Image.filters.Grayscale(),
        new fabric.Image.filters.Brightness({ brightness: 10 })
      );
      img.applyFilters(canvas.renderAll.bind(canvas));
      canvas.add(img);
    });
  

テキスト

テキストも図形と同じように扱える。


    var canvas = new fabric.Canvas('c');
    canvas.add(new fabric.Text("jsCafe", {
      left: 0, top: 0,
      fill: '#5fcc28',
      fontSize: 30
    }));
    canvas.add(new fabric.Text("jsCafe", {
      left: 150, top: 0,
      fill: '#fff',
      stroke: 'blue',
      strokeWidth: 2,
      fontFamily: 'sans-serif',
      fontSize: 50
    }));
    canvas.add(new fabric.Text("jsCafe", {
      left: 400, top: 0,
      fill: '#fff',
      fontSize: 30,
      angle: 20,
      textDecoration: 'underline'
    }));
  

アニメーション

絶対値だけでなく、相対値による指定もできる


    var canvas = new fabric.Canvas('c');
    var redRect = new fabric.Rect({ left: 10, top: 10, fill: 'red', width: 20, height: 20 });
    var blueRect = new fabric.Rect({ left: 30, top: 30, fill: 'blue', width: 20, height: 20 });
    canvas.add(redRect);
    canvas.add(blueRect);

    function move() {
      // 絶対値で指定
      redRect.animate('left', 70, {
        onChange: canvas.renderAll.bind(canvas)
      });
      // 相対値で指定
      blueRect.animate('left', '+=30', {
        onChange: canvas.renderAll.bind(canvas),
        easing: fabric.util.ease.easeOutBounce
      });
    }
    document.getElementById('button').addEventListener('click', move);
  

グループ化

複数の図形を、1つの図形としてマウスで動かせる


    var canvas = new fabric.Canvas('c');
    var ellipse = new fabric.Ellipse({
      fill: '#f09cdb', rx: 160, ry: 40
    });
    var text = new fabric.Text("jsCafe", {
      left: 80, top: 20
    });

    var group = new fabric.Group([ellipse, text], {
      left: 10,
      top: 10
    });
    canvas.add(group);
  

イベント

図形の追加時、選択時、選択解除時、などイベントが発生


    var canvas = new fabric.Canvas('c');
    canvas.on('object:selected', function(options) {
      alert(options.target.fill);
    });
    canvas.on('selection:cleared', function(options) {
      alert('cleared!');
    });

    var rect = new fabric.Rect({
      left: 10, top: 10, fill: 'red', width: 20, height: 20
    });
    canvas.add(rect);
  

エクスポート

Json、SVGでエクスポート。逆にインポートすることも。


    var canvas = new fabric.Canvas('c');
    var rect = new fabric.Rect({
      left: 10, top: 10, fill: 'red', width: 20, height: 20
    });
    canvas.add(rect);

    function toSVG() {
      alert(canvas.toSVG());
    }
    document.getElementById('button').addEventListener('click', toSVG);
  

使ってみた

  • そもそもCanvasってどういうときに使うんだろう・・・
    • Flappy Birdを真似たゲームを作ってみた =>Flappy Ball
    • 他にもCacooの超超超劣化版みたいなの作り始めてみた
  • MV*フレームワークと一緒に使おうとした(データバインディングしたい欲求が出てきた)
    • どうやって一緒に使ったらいいのか分からなかった(MV*フレームワーク使いこなせてない...)
    • CanvasとかSVGとかのライブラリとMV*フレームワークってどうやって一緒に使えばいいんだろう・・・?
    • Backboneは独自のモデルを作る必要があるので、もしかして相性悪い・・・?
  • 素のCanvasAPIを使うよりコードが見やすい。インタラクティブな操作も最初から着いてくる。コーディング楽しかった。

おしまい