Fabricjs How to scale an object, but fix the width of the frame (stroke)

I am developing a fabricjs based chart tool. Our tool has its own svg-based form collection. My problem is that I am scaling an object, scale (stroke). My question is: how can I scale the object, but fix the stroke width. Check attachments. small version

scaled version

Many thanks!

+5
fabricjs
source share
2 answers

Here is a simple example where, on an object scale, we keep a reference to the original stroke and calculate a new stroke based on the scale.

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> 
+7
source share

I found what seems like an even better solution, works great with SVG tracks.

You can override the fabricjs _renderStroke method and add ctx.scale(1 / this.scaleX, 1 / this.scaleY); to ctx.stroke(); as shown below.

 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(); }; 

You may also need to override fabric.Object.prototype._getTransformedDimensions to adjust the bounding box to account for the difference in size.

In addition, a more complete implementation is likely to add an object-object property to conditionally control this change for both overridden methods.

+1
source share

All Articles