Javascript 缩放后Fabricjs画布重置

Javascript 缩放后Fabricjs画布重置,javascript,fabricjs,Javascript,Fabricjs,我有一个画布,我需要能够放大和缩小,也改变了图像/对象内几次 为此,我在第一次加载页面时设置画布,如下所示: fabric.Object.prototype.hasBorders = false; fabric.Object.prototype.hasControls = false; canvas = new fabric.Canvas('my_canvas', {renderOnAddRemove: false, stateful: false}); canvas.defaultCurs

我有一个画布,我需要能够放大和缩小,也改变了图像/对象内几次

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

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);
    });
  }
}
然后,当我需要更改画布中的图像/对象或页面重新加载时,我会尝试如下方式重置画布:

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之前,这一切都很好。根据线程,在此之后,当我重置缩放或在画布缩放时用鼠标单击画布时,图像/对象开始改变位置,似乎在左上角方向的每次更改时都会跳跃,最终从视图中消失

重置缩放:

canvas.setZoom(1);
resetCanvas(); //(above method)
如何恢复图像/对象位置

我试着做了初始设置,而不是重置和缝合,以直观地工作,但实际上是增加了一个新的上层画布层在每个新的设置,所以这是没有好处的


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

请参见下面的代码片段-我在这里也做了同样的操作-将对象放大,但如果有人点击它,请将对象分组

可以解决获取原始对象属性的问题,将组解组并创建它们的副本,然后重新附加-有点烦人,但这是我找到的唯一解决方案

<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>

//画布和办公室背景
var mainGroup;
var canvas=this.\uu canvas=newfabric.canvas('c');
fabric.Object.prototype.transparentCorners=false;
fabric.Object.prototype.originX=fabric.Object.prototype.originY='center';
创建对象(画布);
//事件-缩放
$(canvas.wrapperEl).on('mousewheel',函数(e){
var target=canvas.findTarget(e);
var delta=e.originalEvent.wheelDelta/5000;
如果(目标){
target.scaleX+=delta;
target.scaleY+=delta;
//约束
如果(target.scaleX<0.1){
target.scaleX=0.1;
target.scaleY=0.1;
}
//约束
如果(target.scaleX>10){
target.scaleX=10;
target.scaleY=10;
}
target.setCoords();
canvas.renderAll();
返回false;
}
});
//鼠标落下
canvas.on('mouse:up',函数(选项){
if(options.target){
var thisTarget=options.target;
var mousePos=canvas.getPointer(options.e);
if(thisTarget.isType('group')){
//解组
控制台日志(鼠标点);
var clone=thisTarget.\u objects.slice(0);
此目标。_restoreObjectsState();
对于(变量i=0;i如果(mousePos.x>=o.originalLeft-o.currentWidth/2&&mousePos.x=o.originalTop-o.currentHeight/2&&mousePos.y我最终解决了我遇到的问题

为了重置缩放,我没有仅使用
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();

虽然这个问题很老,但下面是我使用fabric.js 2.2.4的当前版本所做的:

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

仅供参考:缩放到一个点是重新计算视口变换。上面的矩阵是这是初始视口变换矩阵。

画布中只有一个对象,没有组