Один обходной путь, кажется, переопределяет toCanvasElement с:
const canvas = new fabric.Canvas('canvas-1', {
imageSmoothingEnabled: false
});
canvas.toCanvasElement = function (multiplier, cropping) {
multiplier = multiplier || 1;
cropping = cropping || {};
var scaledWidth = (cropping.width || this.width) * multiplier,
scaledHeight = (cropping.height || this.height) * multiplier,
zoom = this.getZoom(),
originalWidth = this.width,
originalHeight = this.height,
newZoom = zoom * multiplier,
vp = this.viewportTransform,
translateX = (vp[4] - (cropping.left || 0)) * multiplier,
translateY = (vp[5] - (cropping.top || 0)) * multiplier,
originalInteractive = this.interactive,
newVp = [newZoom, 0, 0, newZoom, translateX, translateY],
originalRetina = this.enableRetinaScaling,
canvasEl = fabric.util.createCanvasElement(),
originalContextTop = this.contextTop;
canvasEl.width = scaledWidth;
canvasEl.height = scaledHeight;
this.contextTop = null;
this.enableRetinaScaling = false;
this.interactive = false;
this.viewportTransform = newVp;
this.width = scaledWidth;
this.height = scaledHeight;
this.calcViewportBoundaries();
var ctx = canvasEl.getContext('2d'); // replaced
ctx.imageSmoothingEnabled = false; // this.renderCanvas(canvasEl.getContext('2d'), this._objects);
this.renderCanvas(ctx, this._objects); // with these 3 lines
this.viewportTransform = vp;
this.width = originalWidth;
this.height = originalHeight;
this.calcViewportBoundaries();
this.interactive = originalInteractive;
this.enableRetinaScaling = originalRetina;
this.contextTop = originalContextTop;
return canvasEl;
};