Maintain Image Stroke Width
by Steve Eberhardt
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.min.js"></script>
<button id="skew-selected">Skew Selected</button>
<canvas id="c" width="500" height="400" class="c"></canvas>
CSS
canvas {
border: 1px solid grey;
}
JavaScript
var canvas = new fabric.Canvas('c');
var imageSrc = "http://fabricjs.com/assets/dragon.jpg";
fabric.Image.fromURL(imageSrc, function(img) {
img.set({
left: 40,
scaleX: 0.18,
scaleY: 0.18,
top: 40,
strokeWidth: 50,
stroke: '#ccc',
paintFirst: 'stroke'
}, {
crossOrigin: 'anonymous'
});
canvas.add(img);
});
//bounding box and control positions are incorrect when image is skewed
$('#skew-selected').on('click', function() {
var obj = canvas.getActiveObject();
obj.set('skewX', 10);
obj.setCoords();
canvas.renderAll();
});
//override stroke rendering for constant stroke width independent of scaling
fabric.Image.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();
};
//modify method for calculating control and bounding box positions
fabric.Image.prototype._getTransformedDimensions = function(skewX, skewY) {
if (typeof skewX === 'undefined') {
skewX = this.skewX;
}
if (typeof skewY === 'undefined') {
skewY = this.skewY;
}
var dimensions = this._getNonTransformedDimensions();
if (skewX === 0 && skewY === 0) {
return {
x: dimensions.x * this.scaleX + (this.strokeWidth * (1 - this.scaleX)),
y: dimensions.y * this.scaleY + (this.strokeWidth * (1 - this.scaleY))
};
}
var dimX = dimensions.x / 2,
dimY = dimensions.y / 2,
points = [{
x: -dimX,
y: -dimY
},
{
x: dimX,
y: -dimY
},
{
x: -dimX,
y: dimY
},
{
x: dimX,
y: dimY
}
],
i, transformMatrix = this._calcDimensionsTransformMatrix(skewX, skewY, false),
bbox;
...