Это похоже на проблему отсечения. Похоже, вам нужно пересчитать позицию CanvasRenderingContext, используя метод translate. Я могу поделиться с вами своей функцией отсечения, которая учитывает все эти факторы и над которой я сейчас работаю. Я использую эту функцию обрезки только на изображениях, но я предполагаю, что она должна работать аналогичным образом и на полигонах, на методе http://fabricjs.com/docs/fabric.Polygon.html#clipTo.
export class ObjectClippingService {
private _zoomRateService: X.ZoomRateService
private _window: any
constructor(zoomRateService: X.ZoomRateService, window: ng.IWindowService) {
this._zoomRateService = zoomRateService
this._window = window
}
public clipping(ctx, target, isOriginalSize?: boolean) {
var rectObj
var left
var top
var angle
var zoomRate = this._zoomRateService.dynamicZoomRate
if (!!isOriginalSize) {
zoomRate = 1
}
ctx.save()
ctx.setTransform(1, 0, 0, 1, 0, 0)
if (this.isGroupImageFrame(target)) {
rectObj = target.getObjects('rect')[0]
left = (target.left + rectObj.left + target.width * target.scaleX / 2) * zoomRate
top = (target.top + rectObj.top + target.height * target.scaleY / 2) * zoomRate
} else {
left = target.left * zoomRate
top = target.top * zoomRate
}
angle = target.angle * Math.PI / 180
console.log('Rotating the clipping by: ' + angle)
ctx.translate(left, top)
ctx.rotate(angle)
this.clipTheImage(target, ctx, zoomRate)
ctx.restore()
}
private isGroupImageFrame(target): boolean {
return target.fixedItem === 'image' && target.type === 'group' && !target.isFrame && target.newGroupType !== 'circle'
}
private rectFrame(target, ctx, zoomRate) {
var rectObj = !!this.isGroupImageFrame(target) ? target.getObjects("rect")[0] : target
const clippingRectWidth = rectObj.width * zoomRate * rectObj.scaleX
const clippingRectHeight = rectObj.height * zoomRate * rectObj.scaleY
ctx.rect(0, 0, clippingRectWidth, clippingRectHeight)
}
private circleFrame(target, ctx, zoomRate) {
var width = target.width * zoomRate * target.scaleX / 2
ctx.arc(width, width, width, 0, Math.PI * 2, false)
}
private clipTheImage(target, ctx, zoomRate) {
if (target.newGroupType == 'rect') this.rectFrame(target, ctx, zoomRate)
if (target.newGroupType === 'circle') this.circleFrame(target, ctx, zoomRate)
}
}
Я вызываю сервис внутри метода clipTo:
fabric.Image.fromURL(src, function (img: any) {
img.set({
...,
clipTo: (ctx) => {
return X._objectClippingService.clipping(ctx, customTarget);
}
});
})