私はfabricjsに基づいたダイアグラムツールを開発しています。私たちのツールには、svgベースの独自の形状コレクションがあります。私の問題は、オブジェクトを拡大縮小するときに、境界線(ストローク)も拡大縮小することです。私の質問は、オブジェクトを拡大縮小し、ストローク幅を固定したままにするにはどうすればよいですか。添付ファイルを確認してください。
どうもありがとうございました!
これは、オブジェクトの縮尺で元のストロークへの参照を保持し、縮尺に基づいて新しいストロークを計算する簡単な例です。
var canvas = new fabric.Canvas('c', { selection: false, preserveObjectStacking:true });
window.canvas = canvas;
canvas.add(new fabric.Rect({
left: 100,
top: 100,
width: 50,
height: 50,
fill: '#faa',
originX: 'left',
originY: 'top',
stroke: "#000",
strokeWidth: 1,
centeredRotation: true
}));
canvas.on('object:scaling', (e) => {
var o = e.target;
if (!o.strokeWidthUnscaled && o.strokeWidth) {
o.strokeWidthUnscaled = o.strokeWidth;
}
if (o.strokeWidthUnscaled) {
o.strokeWidth = o.strokeWidthUnscaled / o.scaleX;
}
})
canvas {
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.4/fabric.min.js"></script>
<canvas id="c" width="600" height="600"></canvas>
私は、さらに優れたソリューションのように感じられ、SVGパスで非常にうまく機能することを発見しました。
以下に示すように、fabricjsの__renderStroke
_メソッドをオーバーライドし、ctx.scale(1 / this.scaleX, 1 / this.scaleY);
の前にctx.stroke();
を追加できます。
_fabric.Object.prototype._renderStroke = function(ctx) {
if (!this.stroke || this.strokeWidth === 0) {
return;
}
if (this.shadow && !this.shadow.affectStroke) {
this._removeShadow(ctx);
}
ctx.save();
ctx.scale(1 / this.scaleX, 1 / this.scaleY);
this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);
this._applyPatternGradientTransform(ctx, this.stroke);
ctx.stroke();
ctx.restore();
};
_
サイズの違いを考慮してバウンディングボックスを調整するには、_fabric.Object.prototype._getTransformedDimensions
_をオーバーライドする必要がある場合もあります。
また、より完全な実装では、ファブリックオブジェクトプロパティを追加して、オーバーライドされた両方のメソッドのこの変更を条件付きで制御することもできます。
次のプロパティがあります:strokeUniformこのように使用しますshape.set({stroke: '#f55b76'、strokeWidth:2、strokeUniform:true})
別の方法は、スケーリングされたオブジェクトに新しいオブジェクトを描画し、スケーリングされたオブジェクトを削除することです。
object.on({
scaled: function()
{
// store new widht and height
var new_width = this.getScaledWidth();
var new_height = this.getScaledHeight();
// remove object from canvas
canvas.remove(this);
// add new object with same size and original options like strokeWidth
canvas.add(new ...);
}
});
私にぴったりです。