裁剪图像时,新图像获取canvas padding fabric js

问题描述

首先,查看显示问题的视频 https://drive.google.com/file/d/1vcJC4qKToIbGeSQ0WNlJuAuWcT0rBeVZ/view

链接到github存储库
https://github.com/alvaropsouza/web-image-editor

裁剪功能运行良好,准确裁剪了所选区域。真正的问题是在创建裁剪图像时,它以某种方式获得了画布填充,使用户更难找到图像边框以进行缩放、调整大小等...

PS:将新的图像填充设置为零将不起作用...此外,当我尝试更改其宽度和高度功能时,裁剪无法正常工作,就像选择错误一样

裁剪函数脚本

var lastSelectedPicture = null;
var isInsertingCropRectangle = false;


var crop_rect,isDown,origX,origY,mask,target;
var done = false;

// IMAGEM DE PLANO DE FUNDO
var src = "https://i.imgur.com/nnCUr4g.jpg";
fabric.Image.fromURL(src,function(img) {
  img.dirty = true;
  img.selectable = false;
  canvas.add(img);
  canvas.renderAll();

canvas.setBackgroundImage(img,canvas.renderAll.bind(canvas),{
  scaleX: canvas.width / img.width,scaleY: canvas.height / img.height
})
});

// IMAGEM A SER RECORTADA
fabric.Image.fromURL(src,function(img) {
  img.selectable = true;
  img.id = 'target';
  img.borderColor = 'red'
  
  img.scaleX = canvas.width / img.width
  img.scaleY = canvas.height / img.height
  img.objectCaching = true,img.statefullCache = true,canvas.add(img);
  canvas.renderAll();
})

canvas.on('object:added',function(e) {
  target = null;
  mask = null;
  canvas.forEachObject(function(obj) {
    //alert(obj.get('id'));
    var id = obj.get('id');
    if (id === 'target') {
      target = obj;
       canvas.setActiveObject(obj);
   }
    if (id === 'mask') {
      //alert(done);
      //alert('mask');
      mask = obj;
    }
  });
});

canvas.on('object:modified',function(e) {
  e.target.setCoords();
  canvas.renderAll();
});

//////////////////////////////////////////////////////////
// MASK
//////////////////////////////////////////////////////////
document.getElementById("mask").addEventListener("click",function() {
    isInsertingCropRectangle = true;
        canvas.discardActiveObject();
        lastSelectedPicture.selectable = false;
        lastSelectedPicture.setCoords();
        lastSelectedPicture.dirty = true;
        canvas.renderAll();
        canvas.discardActiveObject();
        isInsertingCropRectangle = true;
});

//////////////////////////////////////////////////////////
// CROP
//////////////////////////////////////////////////////////
document.getElementById("crop").addEventListener("click",function() {
  if (target !== null && mask !== null) {
    console.log(mask,'01')
    console.log(crop_rect,'02')
        // Re-scale mask
    mask = rescaleMask(target,mask);
    mask.setCoords();
    // Do the crop
    target.clipPath = mask;
    
    target.dirty=true;
    canvas.setActiveObject(target);
    canvas.bringToFront(target);
    target.selectable = true;
    canvas.remove(mask)
    canvas.renderAll();
  }
});

//////////////////////////////////////////////////////////
// RE-SCALE MASK FOR CROPPING
//////////////////////////////////////////////////////////
function rescaleMask(target,mask){
  mask.scaleX = 1;
  mask.scaleY = 1;

  mask.scaleX/=target.scaleX;
  mask.scaleY/=target.scaleY;
 
  var targetCenterX = target.width * target.scaleX / 2;
    var targetCenterY = target.height * target.scaleY / 2;

  var maskOverlapX = mask.left  - target.left;
  var maskOverlapY = mask.top - target.top;
    var centerBasedX = maskOverlapX - targetCenterX;
    var centerBasedY = maskOverlapY - targetCenterY;

  if( maskOverlapX >= targetCenterX){
    centerBasedX = (maskOverlapX - targetCenterX)/target.scaleX;
  }
  else{
 
    centerBasedX = (-(targetCenterX) + maskOverlapX)/target.scaleX;
  }

  if( maskOverlapY >= targetCenterY){
    centerBasedY = (maskOverlapY - targetCenterY)/target.scaleY;
  }
  else{
    centerBasedY = (-(targetCenterY) + maskOverlapY)/target.scaleY;
  }

  mask.left = centerBasedX;
  mask.top = centerBasedY;
  mask.originX = 'left';
  mask.originY = 'top';
  mask.setCoords();
  mask.dirty=true;
  canvas.renderAll();
  
  //var newMask = mask;
  return mask;
}

canvas.on('mouse:down',function(o) {
    if( isInsertingCropRectangle == true ){
    if (done) {
      canvas.renderAll();
      return;
    }
    isDown = true;
    var pointer = canvas.getPointer(o.e);
    origX = pointer.x;
    origY = pointer.y;
    crop_rect = new fabric.Rect({
      left: origX,top: origY,width: pointer.x - origX,height: pointer.y - origY,opacity: .3,transparentCorners: false,selectable: true,id: 'mask',borderColor: 'red'
    });
    canvas.add(crop_rect);
    canvas.renderAll();
  }
});

canvas.on('mouse:move',function(o) {
    if( isInsertingCropRectangle == true ){
    if (done) {
      canvas.renderAll();
      return;
    }
    if (!isDown) return;
    var pointer = canvas.getPointer(o.e);

    if (origX > pointer.x) {
      crop_rect.set({
        left: Math.abs(pointer.x)
      });
    }
    if (origY > pointer.y) {
      crop_rect.set({
        top: Math.abs(pointer.y)
      });
    }

    crop_rect.set({
      width: Math.abs(origX - pointer.x)
    });
    crop_rect.set({
      height: Math.abs(origY - pointer.y)
    });


    crop_rect.setCoords();
    canvas.renderAll();
  }
  else{
  
  }
});

canvas.on('mouse:up',function(o) {
    if( isInsertingCropRectangle == true ){
    if (done) {
      canvas.renderAll();
      return;
    }
    isDown = false;

    crop_rect.set({
      selectable: true
    });
    done = true;
  }
  else{
  
  }
});

    canvas.on('selection:created',function(event) {
        selectionChanged(event);
  });
    
    canvas.on('selection:updated',function(event) {
        selectionChanged(event);
    });

    function selectionChanged(event){
    switch(event.target.type) {
      case 'textBox':
        break;
        case 'image':
          lastSelectedPicture = event.target;
                break;
            case 'rect':
                break;
            case 'group':
                break;
            default:
                break;
        }
        
    }

解决方法

您当前正在使用 clipPaths 裁剪图像,该图像始终保持原始对象的尺寸,而不是 clipPath 的尺寸(请参阅 http://fabricjs.com/clippath-part1)。尝试使用图像属性 widthheightcropXcropY 来实现您的裁剪效果,这将使图像的边界框具有正确的尺寸。

img.set({ width:100,height:100,cropX: 50,cropY: 50 });