これはプロパティを使用して Fabric で実現できますclipToが、関数で変換 (スケールと回転) を「反転」する必要がありclipToます。
clipToFabric でプロパティを使用すると、クリッピングの後にスケーリングと回転が適用されます。つまり、クリッピングは画像と共にスケーリングおよび回転されます。プロパティ関数で変換の正確な逆を適用することで、これに対抗する必要があります。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/