裁剪图像时,新图像获得 canvas padding fabric js
When image is cropped, the new image gets the canvas padding fabric js
Link 到 github 存储库
https://github.com/alvaropsouza/web-image-editor
裁剪功能工作得很好,它裁剪了选定的区域。真正的问题是当创建裁剪图像时,它以某种方式获得 canvas 填充,使用户更难找到图像边界以进行缩放、调整大小等...
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)。尝试使用图像属性 width
、height
、cropX
和 cropY
来实现裁剪效果,这将使图像的边界框具有正确的尺寸。
img.set({ width:100, height:100, cropX: 50, cropY: 50 });
Link 到 github 存储库
https://github.com/alvaropsouza/web-image-editor
裁剪功能工作得很好,它裁剪了选定的区域。真正的问题是当创建裁剪图像时,它以某种方式获得 canvas 填充,使用户更难找到图像边界以进行缩放、调整大小等...
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)。尝试使用图像属性 width
、height
、cropX
和 cropY
来实现裁剪效果,这将使图像的边界框具有正确的尺寸。
img.set({ width:100, height:100, cropX: 50, cropY: 50 });