【问题标题】:FabricJS Polygon object is over-offsetFabricJS 多边形对象过度偏移
【发布时间】:2020-02-26 02:42:40
【问题描述】:

我正在开发一个由多个对象组成的界面。我正在尝试处理画布/界面调整大小的情况。偏移都已正确处理,但有两个顽固的对象拒绝正确偏移/渲染(图 1)。在调整界面大小之前,所有对象都已正确定位(图 2)。

有问题的两个对象都是多边形类型,而其余的则不是。这让我怀疑多边形可能需要一些额外的步骤。

我已经检查了所有的偏移量和点坐标,并且所有的值都被正确分配了,但它仍然是过度偏移的,当它被选中时会被切断。

处理这些对象的代码有数千行,因此不可能全部共享。 不过,根据描述和截图,有什么明显的突出之处吗?

图 1

图 2

【问题讨论】:

    标签: canvas html5-canvas fabricjs


    【解决方案1】:

    看起来像是剪辑问题。看起来您需要使用其 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);
            }
        });
    })
    

    【讨论】:

    • 根据文档,clipTo 自 2.0.0 以来已被弃用,我使用的是 2.3.3,但我会试一试,看看结果如何。感谢您的回复。
    猜你喜欢
    • 2019-12-17
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    • 2012-10-26
    • 2014-10-07
    相关资源
    最近更新 更多