javascript 使用 FabricJs 的裁剪功能
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18732876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Crop Functionality using FabricJs
提问by John
How to implement crop tool on the image that is loaded on the canvas using fabric.js ? I have a image loaded on the canvas .Now i want to implement crop tool where the user is allowed to crop the image and reload it on to the canvas when he is done.
如何使用 fabric.js 在画布上加载的图像上实现裁剪工具?我在画布上加载了一个图像。现在我想实现裁剪工具,允许用户裁剪图像并在完成后将其重新加载到画布上。
采纳答案by Tom
In Summary
总之
- set
el.selectable = false
- draw a rectangle on it with mouse event
- get rectangle left/top and width/height
- then use the following function
- 放
el.selectable = false
- 用鼠标事件在其上绘制一个矩形
- 获取矩形左侧/顶部和宽度/高度
- 然后使用以下功能
Sorry, let me explain. The ctx.rect
will crop the image from the center point of the object. Also the scaleX
factor should be taken into account.
对不起,让我解释一下。该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);
}
Complete example: http://jsfiddle.net/hellomaya/kNEaX/1/
完整示例:http: //jsfiddle.net/hellomaya/kNEaX/1/
And check out this http://jsfiddle.net/hellomaya/hzqrM/for generating the select box. And a reference for the Fabric events: https://github.com/kangax/fabric.js/wiki/Working-with-events
并查看此http://jsfiddle.net/hellomaya/hzqrM/以生成选择框。以及 Fabric 事件的参考:https: //github.com/kangax/fabric.js/wiki/Working-with-events
回答by Kirby
(This answer is an iteration on the fiddle in Tom'sanswer. Thank you, Tom, for getting me down the road.)
(这个答案是对汤姆答案中小提琴的迭代。谢谢汤姆,让我走上这条路。)
You can crop in Fabric.js using either fabric.Object.clipTo()or fabric.Object.toDataURL(). The clipTo()
method retains the original image and displays a crop via a mask. The toDataURL()
method creates a new image.
您可以使用fabric.Object.clipTo()或fabric.Object.toDataURL()在 Fabric.js 中进行裁剪。该clipTo()
方法保留原始图像并通过蒙版显示裁剪。该toDataURL()
方法创建一个新图像。
My full example uses the clipTo()
method. I have included a small chunk of code at the end showing the toDataURL()
method.
我的完整示例使用了该clipTo()
方法。我在最后包含了一小段代码,显示了该toDataURL()
方法。
Solution 1
方案一
Summary
概括
- Prepare an invisible rectangle. Have it draw when the user clicks and drags mouse across canvas.
- When user releases mouse click, clip the underlying image
- 准备一个看不见的矩形。当用户在画布上单击并拖动鼠标时,让它绘制。
- 当用户释放鼠标点击时,剪辑底层图像
Difference's from Tom's answer
与汤姆的答案不同
In the fiddle in Tom's answer, there are a couple of minor things I wanted to change. So in my example the differences are
在汤姆回答的小提琴中,我想改变一些小事情。所以在我的例子中,差异是
The crop box work from left to right and right to left (Tom's works from right to left only)
You have more than one chance to draw the crop box (attempting to re-draw the crop box in Tom's causes box to jump)
Works with Fabric.js v1.5.0
Less code.
裁剪框从左到右,从右到左(Tom 的作品仅从右到左)
您有不止一次绘制裁剪框的机会(尝试在 Tom 的原因框跳转中重新绘制裁剪框)
适用于 Fabric.js v1.5.0
更少的代码。
The Code
代码
// 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>
Solution 2
解决方案2
Or, instead of using clipTo()
like above, we could generate a new image using toDataURL()
. Something like this
或者,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();
};
});
回答by Frederic Anand
I developed easy and faster cropping of image using latest fabric js version https://github.com/kpomservices/Fabric-JS-Image-CROP
我使用最新的 Fabric js 版本开发了简单快速的图像裁剪 https://github.com/kpomservices/Fabric-JS-Image-CROP
Demo: http://kpomservices.com/imagecropdemo/index.html
演示:http: //kpomservices.com/imagecropdemo/index.html
I used cropx, cropy for maintaining the crop.
我使用cropx,cropy来保持作物。