如何使用fabric.js在画布上加载的图像上实现裁剪工具? 我在画布上加载了一张图片。现在我想要实现裁剪工具,让用户可以裁剪图片,并在完成后重新加载到画布上。
如何使用fabric.js在画布上加载的图像上实现裁剪工具? 我在画布上加载了一张图片。现在我想要实现裁剪工具,让用户可以裁剪图片,并在完成后重新加载到画布上。
(此答案是对 Tom 答案中的 fiddle 进行了迭代。感谢 Tom 帮我走上这条路。)
您可以使用 Fabric.js 中的 fabric.Object.clipTo() 或 fabric.Object.toDataURL() 进行裁剪。 clipTo()
方法保留原始图像,并通过掩模显示剪裁。 toDataURL()
方法创建一个新的图像。
我的完整示例使用了 clipTo()
方法。我在末尾包含了一小段代码,展示了 toDataURL()
方法。
解决方案 1
概述
与 Tom 答案的区别
在 Tom 答案的 fiddle 中,有几个我想要改变的小细节。所以在我的示例中,区别如下
裁剪框从左到右和从右到左都可以工作 (Tom 的只能从右到左)
您有多次机会绘制裁剪框 (在 Tom 的尝试重新绘制裁剪框会导致框跳动)
适用于 Fabric.js v1.5.0
代码更少。
代码
// 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
或者,我们可以使用toDataURL()
生成一个新的图片,而不是像上面那样使用clipTo()
。代码如下:
$('#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();
};
});
onload
时它仍然起作用?而且当我在 toDataURL
后加上警报时,这个警报从未触发? - jose920405总结一下:
el.selectable = false
很抱歉,让我解释一下。 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
object.set({
left: 100,
top: 100,
selectable: false
});
object.hasRotatingPoint = true;
object.scaleX = object.scaleY = 0.25;
object.scaleToWidth(“400”);
object.scaleToHeight(“400”);
canvas.add(object);
canvas.renderAll();
}); - Pavan Hukerikar我使用最新版本的Fabric js开发了轻松快速裁剪图像的功能。 https://github.com/kpomservices/Fabric-JS-Image-CROP
Demo: http://kpomservices.com/imagecropdemo/index.html
我使用cropx、cropy来维护裁剪。
img.toDataURL(...)
。 - kangax