Fabricjs如何缩放对象但保持边框(笔触)宽度固定

tro*_*ngd 10 fabricjs

我正在开发一个基于fabricjs的图表工具.我们的工具有我们自己的形状集合,这是基于svg.我的问题是当我缩放对象时,边界(笔划)比例也是如此.我的问题是:如何缩放对象但保持笔划宽度固定.请检查附件.
小版本

缩放版

非常感谢你!

Ste*_*den 8

这是一个简单的例子,在对象的比例上,我们保持对原始笔划的引用,并根据比例计算新的笔划.

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;
  }
})
Run Code Online (Sandbox Code Playgroud)
canvas {
    border: 1px solid #ccc;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Lon*_*tum 8

有一个属性叫做:strokeUniform 像这样使用 shape.set({stroke: '#f55b76', strokeWidth:2,strokeUniform: true })


byo*_*ngb 6

我发现了一个更好的解决方案,适用于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();
};
Run Code Online (Sandbox Code Playgroud)

您可能还需要覆盖fabric.Object.prototype._getTransformedDimensions以调整边界框以考虑大小的差异.

此外,更完整的实现可能会添加一个结构对象属性,以有条件地控制这两个重写方法的更改.