看起来像是剪辑问题。看起来您需要使用其 translate 方法重新计算 CanvasRenderingContext 的位置。我可以与您分享我的剪辑功能,它考虑了所有这些因素并且我目前正在研究。我只在图像上使用这个裁剪功能,但我认为它也应该在多边形上以类似的方式工作,在其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);
}
});
})