21

如何使用 fabric.js 在画布上加载的图像上实现裁剪工具?我在画布上加载了一个图像。现在我想实现裁剪工具,允许用户裁剪图像并在完成后将其重新加载到画布上。

4

3 回答 3

15

(这个答案是汤姆回答中小提琴的一个迭代。谢谢你,汤姆,让我走上了这条路。)

您可以使用fabric.Object.clipTo()fabric.Object.toDataURL()在 Fabric.js 中进行裁剪。该clipTo()方法保留原始图像并通过蒙版显示裁剪。该toDataURL()方法创建一个新图像。

我的完整示例使用该clipTo()方法。我在最后包含了一小段代码来展示该toDataURL()方法。

解决方案 1

概括

  1. 准备一个不可见的矩形。当用户在画布上单击并拖动鼠标时让它绘制。
  2. 当用户释放鼠标点击时,剪切底层图像

与汤姆的答案不同

在汤姆的回答中,我想改变几件小事。所以在我的例子中,差异是

  1. 裁剪框从左到右和从右到左工作(汤姆的作品只从右到左)

  2. 您有不止一次机会绘制裁剪框(尝试在 Tom's Causes box to jump 中重新绘制裁剪框)

  3. 适用于 Fabric.js v1.5.0

  4. 更少的代码。

编码

 // set to the event when the user pressed the mouse button down
var mouseDown;
// only allow one crop. turn it off after that
var disabled = false;
var rectangle = new fabric.Rect({
    fill: 'transparent',
    stroke: '#ccc',
    strokeDashArray: [2, 2],
    visible: false
});
var container = document.getElementById('canvas').getBoundingClientRect();
var canvas = new fabric.Canvas('canvas');
canvas.add(rectangle);
var image;
fabric.util.loadImage("http://fabricjs.com/lib/pug.jpg", function(img) {
    image = new fabric.Image(img);
    image.selectable = false;
    canvas.setWidth(image.getWidth());
    canvas.setHeight(image.getHeight());
    canvas.add(image);
    canvas.centerObject(image);
    canvas.renderAll();
});
// capture the event when the user clicks the mouse button down
canvas.on("mouse:down", function(event) {
    if(!disabled) {
        rectangle.width = 2;
        rectangle.height = 2;
        rectangle.left = event.e.pageX - container.left;
        rectangle.top = event.e.pageY - container.top;
        rectangle.visible = true;
        mouseDown = event.e;
        canvas.bringToFront(rectangle);
    }
});
// draw the rectangle as the mouse is moved after a down click
canvas.on("mouse:move", function(event) {
    if(mouseDown && !disabled) {
        rectangle.width = event.e.pageX - mouseDown.pageX;
        rectangle.height = event.e.pageY - mouseDown.pageY;
        canvas.renderAll();
    }
});
// when mouse click is released, end cropping mode
canvas.on("mouse:up", function() {
    mouseDown = null;
});
$('#cropB').on('click', function() {
    image.clipTo = function(ctx) {
        // origin is the center of the image
        var x = rectangle.left - image.getWidth() / 2;
        var y = rectangle.top - image.getHeight() / 2;
        ctx.rect(x, y, rectangle.width, rectangle.height);
    };
    image.selectable = true;
    disabled = true;
    rectangle.visible = false;
    canvas.renderAll();
});
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js" type="text/javascript"></script>
</head>
<body>
<canvas style="border: 1px solid black" id="canvas"></canvas>
<button id=cropB>crop</button>
</body>

解决方案 2

或者,clipTo()我们可以使用生成新图像,而不是像上面那样使用toDataURL()。像这样的东西

$('#cropB').on('click', function() {
    image.selectable = true;
    disabled = true;
    rectangle.visible = false;
    var cropped = new Image();
    cropped.src = canvas.toDataURL({
        left: rectangle.left,
        top: rectangle.top,
        width: rectangle.width,
        height: rectangle.height
    });
    cropped.onload = function() {
        canvas.clear();
        image = new fabric.Image(cropped);
        image.left = rectangle.left;
        image.top = rectangle.top;
        image.setCoords();
        canvas.add(image);
        canvas.renderAll();
    };
});
于 2015-09-17T00:13:12.647 回答
13

总之

  1. el.selectable = false
  2. 使用鼠标事件在其上绘制一个矩形
  3. 获取矩形左/上和宽度/高度
  4. 然后使用以下功能

对不起,让我解释一下。将从对象的ctx.rect中心点裁剪图像。也scaleX应该考虑这个因素。

x = select_el.left - object.left;
y = select_el.top - object.top;

x *= 1 / scale;
y *= 1 / scale;

width = select_el.width * 1 / scale;
heigh = select_el.height * 1 / scale;

object.clipTo = function (ctx) {
    ctx.rect (x, y, width, height);
}

完整示例:http: //jsfiddle.net/hellomaya/kNEaX/1/

并查看此http://jsfiddle.net/hellomaya/hzqrM/以生成选择框。以及 Fabric 事件的参考:https ://github.com/kangax/fabric.js/wiki/Working-with-events

于 2013-09-13T06:33:43.300 回答
0

我使用最新的织物 js 版本https://github.com/kpomservices/Fabric-JS-Image-CROP开发了简单快速的图像裁剪

演示: http: //kpomservices.com/imagecropdemo/index.html

我使用cropx,cropy来维持作物。

于 2020-05-29T07:20:47.450 回答