使用 FabricJs 在同一画布上裁剪多个图像

Posted

技术标签:

【中文标题】使用 FabricJs 在同一画布上裁剪多个图像【英文标题】:Crop multiple images on same canvas using FabricJs 【发布时间】:2016-12-20 23:07:38 【问题描述】:

我想将图像添加到画布并一次选择一个并应用裁剪以请看一下: http://jsfiddle.net/kNEaX/586/

原帖:Crop Functionality using FabricJs

var canvas = new fabric.Canvas('c1');
canvas.backgroundColor = "#333";
canvas.renderAll();

var mouseDown;
var r = document.getElementById('c1').getBoundingClientRect();
var src = "http://fabricjs.com/lib/pug.jpg";
var disabled = true;
var scaleX, scaleY
var el


fabric.util.loadImage(src, function(img) 
  object = new fabric.Image(img);
  object.set(
    //      left: 200,
    //      top: 200,
    selectable: true
  );
  object.hasRotatingPoint = true;
  //    object.scaleX = object.scaleY = 0.25;
  canvas.add(object);
  canvas.renderAll();
);




canvas.on("mouse:down", function(event) 
  if (!disabled) 
    el.width = 2;
    el.height = 2;
    el.left = event.e.pageX - r.left;
    el.top = event.e.pageY - r.top;
    el.visible = true;
    mouseDown = event.e;
    canvas.bringToFront(el);
    canvas.renderAll();
  
);

canvas.on("mouse:move", function(event) 

  if (mouseDown && !disabled) 
    el.width = event.e.pageX - mouseDown.pageX;
    el.height = event.e.pageY - mouseDown.pageY;
    canvas.renderAll();
  
);


canvas.on("mouse:up", function(event) 
  mouseDown = null;
  if (disabled === false) 
    cropB()
  
);

$('#cropB-start').on('click', function(event) 

  var obj = canvas.getActiveObject();
  if (obj) 
    disabled = false;

    el = new fabric.Rect(
      fill: 'transparent',
      stroke: '#ccc',
      strokeDashArray: [2, 2],
      visible: false
    );

    el.visible = false;
    canvas.add(el);
    canvas.renderAll();


    obj.set(
      selectable: false
    )
    canvas.renderAll();
  else
  alert('Please select the photo and then click Start Crop, to reset crop click the Reset button')
  

);

$('#cropB-reset').on('click', function(event) 

  var obj = canvas.getActiveObject();

  obj.clipTo = null;
  canvas.renderAll();

);

function cropB() 
  var image = canvas.getActiveObject();

  if (image) 
    scaleX = image.get('scaleX'),
      scaleY = image.get('scaleY')

    image.clipTo = function(ctx) 
      // origin is the center of the image
      var x = el.left - image.getWidth() / 2
      var y = el.top - image.getHeight() / 2
      ctx.rect(x, y, el.width * scaleX, el.height * scaleY);
    ;
    image.selectable = true;
    disabled = true;
    el.visible = false;
    canvas.renderAll();
  
;
body 
  background-color: #ccc;
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>

<canvas style="-moz-user-select: none; cursor: crosshair;"   id="c1"></canvas>
<button id=cropB-start>Start Crop</button>
<button id=cropB-reset>Reset</button>

问题是,如果我为照片添加比例或移动照片,然后应用裁剪,它不会显示正确的裁剪。

请看看小提琴,看看你能做什么。

【问题讨论】:

【参考方案1】:

好的,我遇到了 ClipTo 坐标的问题,我需要在应用 clipTo 函数时考虑图像的左侧和顶部坐标以及图像的比例。

看看修改后的功能。

 function cropB() 

 var image = canvas.getActiveObject();

 if (image) 
   scaleX = image.get('scaleX'),
   scaleY = image.get('scaleY')


     image.clipTo = function(ctx) 

       var x = el.left - image.left - (image.getWidth() / 2),
           y = el.top - image.top - (image.getWidth() / 2),
           width = el.width * 1 / scaleX,
           height = el.height * 1 / scaleY;

           x *= 1 / scaleX;
           y *= 1 / scaleY;

           ctx.rect(x, y, width, height);

      ;

         image.selectable = true;
         disabled = true;
         el.visible = false;
         canvas.renderAll();
 
 ;

【讨论】:

以上是关于使用 FabricJs 在同一画布上裁剪多个图像的主要内容,如果未能解决你的问题,请参考以下文章

使用 FabricJS 裁剪图像

Fabric JS clipPath:裁剪后如何使图像适合画布?

裁剪 Sprite 与单个图像的 Fabric.js 效率

Fabricjs - 在一个文档中渲染多个画布

从画布中删除图像-fabricjs(javascript)

将fabricjs画布转换为base64图像