LoginSignup
5
8

More than 1 year has passed since last update.

【備忘録】逆引きFabric.js

Last updated at Posted at 2022-03-26

はじめに

Fabric.jsの機能で個人的に試したものを備忘録として残す。後日試した機能があれば追記する(かも)。

検証にはVue環境を使用している(下記参照)。
※Fabric.js本体の機能なのでF/Wには依存しない(はず)

実装

選択時の□(拡大/縮小・回転するやつ)を出さない

対象ObjectのhasControlsfalseにする。

素体となるcanvas
<canvas id="theCanvas"></canvas>
描画スクリプト
const rect1 = new fabric.Rect({
  left: 100,
  top: 50,
  width: 31,
  height: 31,
  fill: 'red',
  hasControls: false, // ★
});
const canvas = new fabric.Canvas('theCanvas');
canvas.add(rect1);

コントロール非表示.gif

選択時に前に出さない

CanvasのpreserveObjectStackingtrueにする。

const rect1 = new fabric.Rect({/*赤*/});
const rect2 = new fabric.Rect({/*青*/});
const canvas = new fabric.Canvas('theCanvas', { preserveObjectStacking: true }); // ★
canvas.add(rect1, rect2);

選択時に前に出さない.gif

後から追加するオブジェクトを背面に配置する

Canvas.insertAt()を使用する。

  • 第3引数がfalseの場合は挿入、trueの場合は置換される
  • 挿入の場合、第2引数のインデックスに配置され、元々インデックスが引数値以上のものは後ろにシフトされる
  • インデックスが大きいものが前面に表示される
const rect1 = new fabric.Rect({/*赤*/});
const rect2 = new fabric.Rect({/*緑*/});
const rect3 = new fabric.Rect({/*青*/});
const canvas = new fabric.Canvas('theCanvas', { preserveObjectStacking: true });
canvas.add(rect1, rect2);
canvas.insertAt(rect3, 1, false); // ★

image.png

前面/背面を後から変更する

変更対象のObjectインスタンスのメソッドを利用する。

  • 最前面にする場合はbringToFront()
  • 最背面にする場合はsendToBack()
  • 任意のインデックスにする場合はmoveTo()(対象Objectが引数のインデックスに配置され、元々インデックスが引数値以上のものは後ろにシフトされる)
クリックイベント定義
// 初期描画までは上と同じ
const frontRed = () => { rect1.bringToFront(); };
const frontGreen = () => { rect2.bringToFront(); };
const frontBlue = () => { rect3.bringToFront(); };
const backRed = () => { rect1.sendToBack(); };
const backGreen = () => { rect2.sendToBack(); };
const backBlue = () => { rect3.sendToBack(); };
const midRed = () => { rect1.moveTo(1); };
onClick割当
<button @click="frontRed">赤を最前面</button>
<button @click="frontGreen">緑を最前面</button>
<button @click="frontBlue">青を最前面</button>
<br>
<button @click="backRed">赤を最背面</button>
<button @click="backGreen">緑を最背面</button>
<button @click="backBlue">青を最背面</button>
<br>
<button @click="midRed">赤を真ん中</button>

前面背面制御.gif

オブジェクトの端の座標や中心座標を取得する

オブジェクトのgetPointByOriginメソッドを利用する。

  • 第一引数(originX): 'left' | 'center' | 'right' (それぞれ左端・左右中心・右端)
  • 第二引数(originY): 'top' | 'center' | 'bottom' (それぞれ上端・上下中心・下端)

また、左右・上下とも中心の座標を取得する場合はgetCenterPointメソッドでもよい。

座標取得
      // rect1の定義は上と同じ
      const lt = rect1.getPointByOrigin('left', 'top');
      leftTopPos.x = lt.x;
      leftTopPos.y = lt.y;

      const rb = rect1.getPointByOrigin('right', 'bottom');
      rightBtmPos.x = rb.x;
      rightBtmPos.y = rb.y;

      const center = rect1.getCenterPoint();
      centerPos.x = center.x;
      centerPos.y = center.y;
座標を画面に表示
  <div>
    left-top = ({{leftTopPos.x}}, {{leftTopPos.y}})
  </div>
  <div>
    center = ({{centerPos.x}}, {{centerPos.y}})
  </div>
  <div>
    right-bottom = ({{rightBtmPos.x}}, {{rightBtmPos.y}})
  </div>

image.png
※設定してるサイズより大きい気がする…枠線分が入ってる??

オブジェクトの端や中心を基準座標として配置する

オブジェクトを作成する際のオプションoriginX, originYを設定するとその点が基準座標になる。

  • originX: 'left' | 'center' | 'right' (それぞれ左端・左右中心・右端)
  • originY: 'top' | 'center' | 'bottom' (それぞれ上端・上下中心・下端)

座標を指定するプロパティ名はleft,topだが上で指定した点に合うように配置されるようになる。

    // 座標・サイズは同じ値を使用
    const posAndSize = {
      left: 100,
      top: 50,
      width: 31,
      height: 31,
    };
    const rect1 = new fabric.Rect({ // 赤・デフォルト
      ...posAndSize,
      fill: 'red',
      hasControls: false,
    });
    const rect2 = new fabric.Rect({ // 緑・上下左右中心
      ...posAndSize,
      originX: 'center', // ★
      originY: 'center', // ★
      fill: 'green',
      hasControls: false,
    });
    const rect3 = new fabric.Rect({ // 青・右下端
      ...posAndSize,
      originX: 'right',  // ★
      originY: 'bottom', // ★
      fill: 'blue',
      hasControls: false,
    });
    // 見やすさの都合で緑→赤→青の順に追加
    canvas.add(rect2, rect1, rect3);

image.png
※十字部分が基準座標(100, 50)

枠線を表示する

strokeおよびstrokeXXXという名前のプロパティを設定する。

また、オブジェクトの色(fill)はデフォルトで黒('rgb(0,0,0)')なので、枠線のみ表示させる場合はfillを透明('transparent', 'rgba(0,0,0,0)'など)にする必要がある。

   // rect1, rect2は上と同じ
   const rect3 = new fabric.Rect({
      ...posAndSize,
      originX: 'right',
      originY: 'bottom',
      fill: 'transparent', // 中身の透明化
      stroke: 'blue', // 枠線の色
      strokeWidth: 4, // 枠線の幅
      hasControls: false,
    });

image.png

注意事項: 枠線表示時の座標とサイズについて

基準座標が端にある場合、枠線の外端が基準座標に合うように配置されるが、中身(設定しているサイズの図形)の端が枠線の中心に来るように設定される。(枠線を太い点線にするとわかりやすい)

    const rect1 = new fabric.Rect({
      left: 100,
      top: 50,
      width: 80,
      height: 80,
      fill: 'red',
      stroke: 'blue',
      strokeWidth: 10,
      strokeDashArray: [15, 10],
      hasControls: false,
    });

image.png
※十字部分が基準座標(100, 50)

参考

5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8