I am implementing a system to crop and offset images with fabricjs.
The offset is applied to the image object and the crop is implemented with another rect that is used for the clipPath
.
To offset the images inside their container I’ve implemented a custom property cropOffset
by overriding the _renderFill
method like this:
fabric.Image.prototype['_renderFill'] = function (ctx) {
let elementToDraw = this._element;
if (!elementToDraw) {
return;
}
let scaleX = this._filterScalingX;
let scaleY = this._filterScalingY;
let w = this.width;
let h = this.height;
let min = Math.min;
let max = Math.max;
// crop values cannot be lesser than 0.
let cropX = max(this.cropX, 0);
let cropY = max(this.cropY, 0);
let elWidth = elementToDraw.naturalWidth || elementToDraw.width;
let elHeight = elementToDraw.naturalHeight || elementToDraw.height;
let sX = cropX * scaleX;
let sY = cropY * scaleY;
if (!this.cropOffset) {
this.cropOffset = { x: -(w / 2), y: -(h / 2) };
}
// the width height cannot exceed element width/height, starting from the crop offset.
let sW = min(w * scaleX, elWidth - sX);
let sH = min(h * scaleY, elHeight - sY);
let x = this.cropOffset.x;
let y = this.cropOffset.y;
let maxDestW = min(w, elWidth / scaleX - cropX);
let maxDestH = min(h, elHeight / scaleY - cropY);
this.imageRenderingPosCurrentFrame = { x: x, y: y };
elementToDraw && ctx.drawImage(elementToDraw,
sX, sY, sW, sH,
x, y, maxDestW, maxDestH
);
}
This let’s me do the following.
Move image from:
To:
When I now add a clip path, the crop works as expected even if the clip path is bigger than the image (red is the clip path from a rect and green is the image):
The problem: If I adjust the cropOffset
while having a clip path and move the image outside of its object bounds, there will be an overflow and it flickers when zooming in or out. Visible here (image rendered outside of green border):
Do you have any ideas or hints why this happens?