これはプロパティを使用して Fabric で実現できますclipTo
が、関数で変換 (スケールと回転) を「反転」する必要がありclipTo
ます。
clipTo
Fabric でプロパティを使用すると、クリッピングの後にスケーリングと回転が適用されます。つまり、クリッピングは画像と共にスケーリングおよび回転されます。プロパティ関数で変換の正確な逆を適用することで、これに対抗する必要があります。clipTo
私の解決策にはFabric.Rect
、クリップ領域の「プレースホルダー」として機能することが含まれます (Fabric を使用してオブジェクトを移動し、クリップ領域を移動できるため、これには利点があります。
私のソリューションは、特に(コンテキストについてはコードを参照) のために、 Lo-Dashユーティリティ ライブラリを使用していることに注意してください。_.bind()
壊す
1. ファブリックの初期化
まず、もちろんキャンバスが必要です。
var canvas = new fabric.Canvas('c');
2. クリップ領域
var clipRect1 = new fabric.Rect({
originX: 'left',
originY: 'top',
left: 180,
top: 10,
width: 200,
height: 200,
fill: 'none',
stroke: 'black',
strokeWidth: 2,
selectable: false
});
Rect
これらのオブジェクトに name プロパティを与えclipFor
て、clipTo
関数がクリッピングしたいオブジェクトを見つけられるようにします。
clipRect1.set({
clipFor: 'pug'
});
canvas.add(clipRect1);
クリップ領域に実際のオブジェクトが存在する必要はありませんが、Fabric を使用して移動できるため、管理が容易になります。
3. クリッピング機能
clipTo
コードの重複を避けるために、画像のプロパティで個別に使用される関数を定義します。
Image オブジェクトのangle
プロパティは度単位で格納されているため、これを使用してラジアンに変換します。
function degToRad(degrees) {
return degrees * (Math.PI / 180);
}
findByClipName()
は、 Lo-Dashを使用して、切り取られる Image オブジェクトのプロパティを持つ を検索する便利な関数ですclipFor
(たとえば、下の画像では にname
なります'pug'
)。
function findByClipName(name) {
return _(canvas.getObjects()).where({
clipFor: name
}).first()
}
そして、これは仕事をする部分です:
var clipByName = function (ctx) {
var clipRect = findByClipName(this.clipName);
var scaleXTo1 = (1 / this.scaleX);
var scaleYTo1 = (1 / this.scaleY);
ctx.save();
ctx.translate(0,0);
ctx.rotate(degToRad(this.angle * -1));
ctx.scale(scaleXTo1, scaleYTo1);
ctx.beginPath();
ctx.rect(
clipRect.left - this.left,
clipRect.top - this.top,
clipRect.width,
clipRect.height
);
ctx.closePath();
ctx.restore();
}
注:上記の関数での の使用の説明については、以下を参照してください。this
4.fabric.Image
使用するオブジェクトclipByName()
最後に、イメージをインスタンス化して、次のようにclipByName
関数を使用できるようにします。
var pugImg = new Image();
pugImg.onload = function (img) {
var pug = new fabric.Image(pugImg, {
angle: 45,
width: 500,
height: 500,
left: 230,
top: 170,
scaleX: 0.3,
scaleY: 0.3,
clipName: 'pug',
clipTo: function(ctx) {
return _.bind(clipByName, pug)(ctx)
}
});
canvas.add(pug);
};
pugImg.src = 'https://fabricjs.com/lib/pug.jpg';
何をし_.bind()
ますか?
参照は_.bind()
関数内でラップされていることに注意してください。
_.bind()
以下の2つの理由で使用しています。
Image
参照オブジェクトを渡す必要がありますclipByName()
clipTo
プロパティは、オブジェクトではなくキャンバス コンテキストに渡されます。
基本的に、_.bind()
指定したオブジェクトをthis
コンテキストとして使用する関数のバージョンを作成できます。
ソース
- https://lodash.com/docs#bind
- https://fabricjs.com/docs/fabric.Object.html#clipTo
- https://html5.litten.com/understanding-save-and-restore-for-the-canvas-context/