视网膜上的 fabricjs:新对象跳到左上角

fabricjs on retina: new object jumps to left top

我继续在协作草图工具上工作,并尝试添加视网膜设备支持。如果用户在 ipad 空中创建绘图,目前我有以下行为: small movie

这是我的代码:

this.getZoomLevel = function (height) {
            if (height > 1024) {
                return 1024 / height;
            } else {
                return height / 1024;
            }
        };  

this.calculateCanvasSize = function(pHeight, pWidth) {
            var result = {
                height: 0,
                width: 0
            };

            while (result.width < pWidth - 1 && result.height < pHeight - 1) {
                result.height = result.height + 1;
                result.width = result.height * 4 / 3;
            }
            return result;
        }; 

this.initCanvas = function () {
            try {
                var parent = document.getElementsByClassName('komaso-canvas-container')[0];
                var canvasSize = this.calculateCanvasSize(parent.clientHeight, parent.clientWidth);

                var canvasHtml = "<div id='wrapper-" + this.Id + "' class='whiteboard-canvas-wrapper' data-ng-show='CurrentPage.Id==" + this.Id + "'><canvas width='" + canvasSize.width + "' height='" + canvasSize.height + "' id='whiteboard-" + this.Id + "' class='whiteboard'><p>Your brower does not support Canvas/p></canvas></div>";
                $(parent).append($compile(canvasHtml)(scope));

                this.Canvaso = document.getElementById(this.HtmlId);

                if (!this.Canvaso) {
                    console.log('Error: Cannot find the imageView canvas element!');
                    return;
                }

                if (!this.Canvaso.getContext) {
                    console.log('Error: no canvas.getContext!');
                    return;
                }

                this.FabricCanvas = new fabric.Canvas(this.HtmlId, { selectionColor: 'transparent' });

                this.FabricCanvas.setWidth(canvasSize.width);
                this.FabricCanvas.setHeight(canvasSize.height);

                fabric.Object.prototype.transparentCorners = false;

                this.FabricCanvas.on('mouse:down', this.onMouseDown);
                this.FabricCanvas.on('mouse:up', this.onMouseUp);
                this.FabricCanvas.on('mouse:move', this.onMouseMove);
                this.FabricCanvas.on('object:added', this.onObjectAdded);
                this.FabricCanvas.on('text:editing:exited', self.onTextObjectEdited);

                if (window.devicePixelRatio !== 1) {

                    var c = this.FabricCanvas.getElement(); 
                    var w = c.width, h = c.height;

                    c.setAttribute('width', w * window.devicePixelRatio);
                    c.setAttribute('height', h * window.devicePixelRatio);

                    $(c).width(canvasSize.width);
                    $(c).height(canvasSize.height);

                    c.getContext('2d').scale(window.devicePixelRatio, window.devicePixelRatio);
                }

                this.FabricCanvas.setZoom(this.getZoomLevel(this.Canvaso.height));

                this.ToggleTool(self.CurrentTool.ToolName);
                this.WhiteboardInitiated = true;
            } catch (e) {
                console.log(e);
            }
        };

getZoomLevel returns 传递给 fabric js canvas 对象的 SetZoom 方法的值。我们决定让所有客户端 canvas 方面都是 4:3 并且默认维度是 1024*768。所以根据这个尺寸我们计算缩放系数。

根据 4:3 规则计算 canvas 的 returns 宽度和高度。

如果您对如何解决此错误行为有任何想法,请post发表评论。提前致谢!

我建议你更新到支持视网膜的 fabricjs 版本(获取 1.6.2)。

如果出于任何原因你不能,我认为问题出在这里:

if (window.devicePixelRatio !== 1) {
   var c = this.FabricCanvas.getElement(); 
   ...
   c.getContext('2d').scale(window.devicePixelRatio, window.devicePixelRatio);
}

getContext return 一个新的上下文。这不是 fabric 稍后要渲染的上下文。如果你想让视网膜启用 lowerCanvas,你必须缩放 this.FabricCanvas.contextContainer,它在 fabric.Canvas 初始化时被创建和引用。

无论如何我建议你换用更新的结构。