首页 文章

Fabricjs画布在缩放后重置

提问于
浏览
7

我有一个fabricjs画布,我需要能够放大和缩小,并且还可以多次更改图像/对象 .

为此我在第一次加载页面时设置了画布,如下所示:

fabric.Object.prototype.hasBorders = false;
fabric.Object.prototype.hasControls = false;

canvas = new fabric.Canvas('my_canvas', {renderOnAddRemove: false, stateful: false});

canvas.defaultCursor = "pointer";
canvas.backgroundImageStretch = false;
canvas.selection = false;
canvas.clear();

var image =  document.getElementById('my_image');
if (image != null) {
  imageSrc = image.src;
  if(imageSrc.length > 0){
    fabric.Image.fromURL(imageSrc, function(img) {
      img = scaleImage(canvas, img); //shrinks the image to fit the canvas
      img.selectable = false;
      canvas.centerObject(img);
      canvas.setActiveObject(img);
      canvas.add(img);
    });
  }
}
canvas.deactivateAll().renderAll();

然后,当我需要更改画布中的图像/对象或页面重新加载时,我尝试重置画布,如下所示:

canvas.clear();
canvas.remove(canvas.getActiveObject());
var image =  document.getElementById('my_image');
if (image != null) {
  imageSrc = image.src;
  if(imageSrc.length > 0){
    fabric.Image.fromURL(imageSrc, function(img) {
      img = scaleImage(canvas, img); //shrinks the image to fit the canvas
      img.selectable = false;
      canvas.centerObject(img);
      canvas.setActiveObject(img);
      canvas.add(img);
    });
  }
}

不确定它是否重要但我更改图像的方式是更改“my_image”中的源并使用上述方法重置画布 .

这很有效,直到我使用 canvas.zoomToPoint ,根据this线程,此后,当我重置缩放时图像/对象开始改变位置,或者在缩放时用鼠标单击画布,似乎跳到左上角的每个变化角落方向,最终从视野中消失 .

重置缩放:

canvas.setZoom(1);
resetCanvas(); //(above method)

如何恢复图像/对象位置?

我尝试进行初始设置而不是重置并接合到视觉上工作,但实际上在每个新设置中添加了一个新的上部画布层,所以它没有用 .

有没有办法将画布重置为原始状态而不会导致此行为,仍然能够正确放大/缩小?

3 回答

  • -1

    虽然这个问题非常陈旧,但这是我使用当前版本的fabric.js 2.2.4所做的:

    canvas.setViewportTransform([1,0,0,1,0,0]);
    

    有关您的信息:缩放到某个点是重新计算视口转换 . 上面的矩阵是初始视口变换矩阵 .

  • 0

    我最终解决了我遇到的问题 .

    要重置缩放,而不是仅使用 canvas.setZoom(1) 将缩放设置为1,我将 canvas.zoomToPoint 方法重新应用到同一点,但使用缩放1,强制进行初始缩放,但是关于用于放大的相同点 .

    至于在画布中恢复图像位置的问题(例如在平移之后),就像删除图像一样简单,将其居中放在画布中并像第一次添加时一样将其重新添加到画布:

    var img = canvas.getActiveObject();
      canvas.remove(img);
      canvas.centerObject(img);
      canvas.setActiveObject(img);
      canvas.add(img);
    
      canvas.renderAll();
    
  • 2

    请参阅下面的代码段 - 我在这里做同样的事情 - 一起缩放,但是在有人点击它的情况下对对象进行分组 .

    获得原始对象属性的问题可以解决,取消组合组并创建它们的副本并重新连接 - 有点烦人,但我发现的唯一解决方案 .

    <script id="main">      
        // canvas and office background
                    var mainGroup;
                    var canvas = this.__canvas = new fabric.Canvas('c');
                    fabric.Object.prototype.transparentCorners = false;
                    fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
    
                    createOnjects(canvas);
    
                    // events - zoom
                    $(canvas.wrapperEl).on('mousewheel', function(e) {
                        var target = canvas.findTarget(e);
                        var delta = e.originalEvent.wheelDelta / 5000;
                        if (target) {
                            target.scaleX += delta;
                            target.scaleY += delta;
    
                            // constrain
                            if (target.scaleX < 0.1) {
                                target.scaleX = 0.1;
                                target.scaleY = 0.1;
                            }
                            // constrain
                            if (target.scaleX > 10) {
                                target.scaleX = 10;
                                target.scaleY = 10;
                            }
                            target.setCoords();
                            canvas.renderAll();
                            return false;
                        }
                    });
                    // mouse down
                    canvas.on('mouse:up', function(options) {
                        if (options.target) {
                            var thisTarget = options.target; 
                            var mousePos = canvas.getPointer(options.e);
                            if (thisTarget.isType('group')) {
                                // unGroup
                                console.log(mousePos);
                                var clone = thisTarget._objects.slice(0);
                                thisTarget._restoreObjectsState();
    
                                for (var i = 0; i < thisTarget._objects.length; i++) {
                                    var o = thisTarget._objects[i];
                                    if (o._element.alt == "officeFloor")
                                        continue;
                                    else {
                                        if (mousePos.x >= o.originalLeft - o.currentWidth / 2 && mousePos.x <= o.originalLeft + o.currentWidth / 2
                                            && mousePos.y >= o.originalTop - o.currentHeight / 2 && mousePos.y <= o.originalTop + o.currentHeight / 2)
                                            console.log(o._element.alt);
                                    }
                                }
    
                                // remove all objects and re-render
                                canvas.remove(thisTarget);
                                canvas.clear().renderAll();             
                                var group = new fabric.Group();
                                for (var i = 0; i < clone.length; i++) {
                                    group.addWithUpdate(clone[i]);
                                }
                                canvas.add(group);
                                canvas.renderAll();
                            }    
                        }
                    });
                    // functions
                    function createOnjects(canvas) {
                        // ToDo: jQuery.parseJSON() for config file (or web service)
                        fabric.Image.fromURL('pics/OfficeFloor.jpg', function(img) {
                        var back = img.set({ left: 100, top: 100 });
                        back._element.alt = "officeFloor";
                        back.hasControls = false;
                        fabric.Image.fromURL('pics/me.png', function(img) {
                        var me = img.set({ left: -420, top: 275 });
                        me._element.alt = "me";
                        console.log(me);
                        var group = new fabric.Group([ back, me], { left: 700, top: 400, hasControls: false });
                        canvas.clear().renderAll();
                        canvas.add(group);
                        // remove all objects and re-render
    
                        });             
                    });
                    }
            </script>
    

相关问题