ここは、技術情報、身の回りに起こった出来事を、「もしかしたらみんなの役に立つかもしれない」と思って書き留めておく場所です。

Image

CanvasライブラリFabric.jsの使い方その2

2019年10月15日
 

前回

「Fabric.jsでCanbasに画像を表示する【使い方】」

に引き続き

HTMLのCanvasライブラリFabric.jsを試していきたいと思います。

 

ステップ5 Canvas全体の拡大・縮小

個別のオブジェクトではなく、全体の拡大・縮小のやり方です。

$(function(){
var zoom = 100;
var zoomStep = 10;
// 準備
var canvas = new fabric.Canvas('cnvs');
canvas.selection = false;	// グループ選択なし

// 時計
fabric.Image.fromURL('/static/fabric/tokei.png', function(oImg) {
	oImg.scaleToWidth(100);
	oImg.set({
		hasRotatingPoint: false,	// 回転なし
		lockScalingFlip: true,	// 裏返しをロック
	});
	canvas.add(oImg);
});
// タンス
fabric.Image.fromURL('/static/fabric/tansu.png', function(oImg) {
	oImg.scaleToWidth(100);
	oImg.set({
		left: 300,
		// hasRotatingPoint: false,	// 回転なし  middle top rotete
		lockScalingFlip: true,	// 裏返しをロック
	});
	oImg.setControlsVisibility({
		 mt: false,	// middle top
		 mb: false,	// middle bottom
		 ml: false,	// middle left
		 mr: false,	// middle right
		 bl: false,	// bottom left
		 //br: false,	// bottom right
		 tl: false,	// top left
		 tr: false,	// top right
		 mtr: false,	// middle top rotete
    }); // 各コントロールをON/OFF制御 右下だけ残す
	canvas.add(oImg);
});
// 拡大
$('#zoomIn').click(function () {
	if (zoom < 100) {
		zoom += zoomStep;
		canvas.setZoom(zoom / 100);
		$('#zoom').val(zoom + '%');
	}
});
// 縮小
$('#zoomOut').click(function () {
	if (zoom > 50) {
		zoom -= zoomStep;
		canvas.setZoom(zoom / 100);
		$('#zoom').val(zoom + '%');
	}
});
});

 

canvas全体の拡大・縮小にはsetZoomを使用します。

1が100%で50%にしたい場合0.5を設定します。

 

ステップ5のデモ(実際に動かせます)

 

ステップ6 Undoの実装

元の状態に戻す方法です。

$(function(){
var undoBuffer = [];
// 準備
var canvas = new fabric.Canvas('cnvs');
canvas.selection = false;	// グループ選択なし

// 時計
fabric.Image.fromURL('/static/fabric/tokei.png', function(oImg) {
	oImg.scaleToWidth(100);
	oImg.set({
		hasRotatingPoint: false,	// 回転なし
		lockScalingFlip: true,	// 裏返しをロック
	});
	canvas.add(oImg);
});

// 図追加
$('#addImage').click(function () {
	undoBuffer.push(canvas.toDatalessJSON());
	console.log(undoBuffer);
	// タンス
	fabric.Image.fromURL('/static/fabric/tansu.png', function(oImg) {
		oImg.scaleToWidth(100);
		oImg.set({
			left: 300,
			// hasRotatingPoint: false,	// 回転なし  middle top rotete
			lockScalingFlip: true,	// 裏返しをロック
		});
		oImg.setControlsVisibility({
			 mt: false,	// middle top
			 mb: false,	// middle bottom
			 ml: false,	// middle left
			 mr: false,	// middle right
			 bl: false,	// bottom left
			 //br: false,	// bottom right
			 tl: false,	// top left
			 tr: false,	// top right
			 mtr: false,	// middle top rotete
	    }); // 各コントロールをON/OFF制御 右下だけ残す
		canvas.add(oImg);
	});
});
// Undo
$('#undo').click(function () {
	canvas.loadFromJSON(undoBuffer.pop()).renderAll();
});
});

canvas.toDatalessJSONメソッドを使用することにより、Canvasの現在の状態をオブジェクトに変換することができます。

JSON文字列ではないので、文字列にしたい場合はJSON.stringifyを使用する必要があります。

要はシリアライズ化ですね。

toDatalessJSONではない、toJSONメソッドもありますが、違いはSVGデータの中身を持つか持たないかのようです。

デモでは「図追加」ボタンを押す前の時点まで戻します。

 

ステップ6のデモ(実際に動かせます)

 

ステップ7 重なり順を変更する

今の状態だと画像のロード順になっているはずなので重なり順を指定します。cssでいうz-indexです。

$(function(){
// 準備
var canvas = new fabric.Canvas('cnvs');
canvas.selection = false;	// グループ選択なし
var tokei, kotatsu, mado, tansu;

// 時計
fabric.Image.fromURL('/static/fabric/tokei.png', function(oImg) {
	tokei = oImg;
    oImg.scaleToWidth(100);
    canvas.add(oImg);
});
// こたつ
fabric.Image.fromURL('/static/fabric/kotatsu.png', function(oImg) {
	kotatsu = oImg;
    oImg.scaleToWidth(100);
    oImg.set('left', 100);
    canvas.add(oImg);
});
// 窓
fabric.Image.fromURL('/static/fabric/mado.png', function(oImg) {
	mado = oImg;
    oImg.scaleToWidth(100);
    oImg.set('left', 200);
    canvas.add(oImg);
});
// タンス
fabric.Image.fromURL('/static/fabric/tansu.png', function(oImg) {
	tansu = oImg;
    oImg.scaleToWidth(100);
    oImg.set('left', 300);
    canvas.add(oImg);
});
// 重ね順指定方法1
$('#stack1').click(function () {
	// 直接順番指定
	mado.moveTo(0);
	tokei.moveTo(1);
	tansu.moveTo(2);
	kotatsu.moveTo(3);
});
// 重ね順指定方法2
$('#stack2').click(function () {
	// 順に前に持っていく
	mado.bringToFront();
	tokei.bringToFront();
	tansu.bringToFront();
	kotatsu.bringToFront();
});
// 重ね順指定方法2
$('#stack3').click(function () {
	// 順に後ろに持っていく
	kotatsu.sendToBack();
	tansu.sendToBack();
	tokei.sendToBack();
	mado.sendToBack();
});
});

まず、moveToメソッドで直接indexを指定する方法です。

indexは0が一番下になるようです。内部の配列のindexなので、length - 1までです。

方法2はbringToFrontメソッドによる一番前に持ってくる方法です。

方法3は逆にsendToBackメソッドで一番後ろに持っていく方法です。

重ね順には、一つ前に持ってくる、一つ後ろに持っていくというメソッドもあります。

また、メソッドは画像のオブジェクトに対して行っていますか、同じメソッッドがcanvasオブジェクトにもあります。

 

ステップ7のデモ(実際に動かせます)

 

ステップ8 背景画像を設定する

画面上の画像とは別に、Canvasの背景に画像を設定することができます。

$(function(){
// 準備
var canvas = new fabric.Canvas('cnvs');
canvas.selection = false;	// グループ選択なし
// 時計
fabric.Image.fromURL('/static/fabric/tokei.png', function(oImg) {
    oImg.scaleToWidth(100);
    canvas.add(oImg);
});
// 背景そのまま
$('#back1').click(function () {
	canvas.setBackgroundImage('/static/fabric/sakura.png', canvas.renderAll.bind(canvas));
});
// 背景あわせる
$('#back2').click(function () {
	fabric.Image.fromURL('/static/fabric/sakura.png', function(sakuraImg) {
		sakuraImg.scaleToWidth(canvas.width);
		sakuraImg.scaleToHeight(canvas.height);
		console.log(sakuraImg.scaleX);
		canvas.setBackgroundImage(sakuraImg, canvas.renderAll.bind(canvas));
	});
});
// 背景縦横中央
$('#back3').click(function () {
	fabric.Image.fromURL('/static/fabric/sakura.png', function(sakuraImg) {
		sakuraImg.scaleToWidth(canvas.width);
		sakuraImg.scaleToHeight(canvas.height);
		canvas.setBackgroundImage(sakuraImg, canvas.renderAll.bind(canvas), {
			left: (canvas.width - sakuraImg.width * sakuraImg.scaleX) / 2
		});
	});
});
});

Canvasサイズ300px x 300pxの大きさに対して、背景画像の大きさは400px x 600pxです。

「画像そのまま」ボタンは、画像をそのままsetBackgroundImageメソッドで設定しています。

「画像あわせる」ボタンは、Canvasサイズの縦横を取得し、背景画像の大きさを設定しています。

「背景縦横中央」ボタンは、背景画像の大きさを設定し、縦横中央になるようにleftをずらしています。

 

ステップ8のデモ(実際に動かせます)

 

まとめ

機能を少し把握してきました。

次は実際に作る時の試行錯誤をまとめていきたいと思っています。