Issue
Link to github repository
https://github.com/alvaropsouza/web-image-editor
The cropping function is working just fine, it crops exactly the area selected. The real problem is when the cropped image is created, somehow it gets the canvas padding, making harder for the user find image borders to zoom, resize etc...
PS: Set the new image padding to zero won't work... Also when i try to change it's width and height function the crop don't work properly, like it's getting the wrong selection
Crop function script
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;
}
}
Solution
You are currently using clipPaths to crop your image which always keep the dimensions of the original object, not the dimensions of the clipPath (see http://fabricjs.com/clippath-part1). Try using the image properties width
, height
, cropX
, and cropY
to achieve your cropping effect instead which will make the image's bounding box have the correct dimensions.
img.set({ width:100, height:100, cropX: 50, cropY: 50 });
Answered By - melchiar Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.