Solución:
target.oCoords.mt
es la esquina superior media.
En su lugar, use la esquina superior derecha: e.target.oCoords.tr
var canvas = new fabric.Canvas('canvas');
var HideControls =
'tl':true,
'tr':false,
'bl':true,
'br':true,
'ml':true,
'mt':true,
'mr':true,
'mb':true,
'mtr':true
;
fabric.Image.fromURL('http://serio.piiym.net/CVBla/txtboard/thumb/1260285874089s.jpg', function (img)
img.top = 60;
img.left = 30;
img.setControlsVisibility(HideControls);
canvas.add(img);
);
canvas.renderAll();
function addDeleteBtn(x, y)
$(".deleteBtn").remove();
var btnLeft = x-10;
var btnTop = y-10;
var deleteBtn = '
';
$(".canvas-container").append(deleteBtn);
canvas.on('object:selected',function(e)
addDeleteBtn(e.target.oCoords.tr.x, e.target.oCoords.tr.y);
);
canvas.on('mouse:down',function(e)
if(!canvas.getActiveObject())
$(".deleteBtn").remove();
);
canvas.on('object:modified',function(e)
addDeleteBtn(e.target.oCoords.tr.x, e.target.oCoords.tr.y);
);
canvas.on('object:scaling',function(e)
$(".deleteBtn").remove();
);
canvas.on('object:moving',function(e)
$(".deleteBtn").remove();
);
canvas.on('object:rotating',function(e)
$(".deleteBtn").remove();
);
$(document).on('click',".deleteBtn",function()
if(canvas.getActiveObject())
canvas.remove(canvas.getActiveObject());
$(".deleteBtn").remove();
);
Hola, sugeriría un enfoque diferente para esta funcionalidad. que es más estable ya que no agrega elementos en el DOM, podemos usarlo en tantos objetos como queramos, no necesitamos ocultar y mostrar los botones de esquina personalizados, y los botones de esquina son visibles cada vez que el objeto es active (funciones nativas de fabricjs).
- Voy a anular el prototipo del objeto. _drawControl función, para agregar mis imágenes de esquina personalizadas.
- Y anula el prototipo de lienzo. _setCornerCursor , para cambiar en tiempo real el cursor del mouse, de acuerdo con la esquina que está encima.
- He hecho un violín en vivo aquí: https://jsfiddle.net/tornado1979/j987gb6f/
UNA. En primer lugar, necesito precargar las imágenes de esquina personalizadas, por lo que cada vez que hagamos clic en un objeto no habrá ningún retraso (utilicé imágenes aleatorias solo para el espectáculo).
var ctrlImages = new Array()
function preload()
for (i = 0; i < preload.arguments.length; i++)
ctrlImages[i] = new Image();
ctrlImages[i].src = preload.arguments[i];
preload(
"https://cdn1.iconfinder.com/data/icons/ui-color/512/Untitled-12-128.png",
"https://cdn2.iconfinder.com/data/icons/social-messaging-productivity-1/128/sync-16.png",
"https://cdn2.iconfinder.com/data/icons/social-messaging-productivity-1/128/write-compose-16.png",
B. Anulo el _drawcontrol (muestro solo el fragmento que cambia las esquinas):
switch (control)
case 'tl':
SelectedIconImage.src = ctrlImages[1].src;//our custom img
break;
case 'tr':
if (flipiX && !flipiY) n='2';
if (!flipiX && flipiY) n='3';
if (flipiX && flipiY) n='4';
SelectedIconImage.src = ctrlImages[0].src;//our custom img
break;
case 'mt':
break;
case 'bl':
if (flipiY) n='2';
SelectedIconImage.src = ctrlImages[3].src;//our custom img
break;
case 'br':
if (flipiX
C. Anular _setCornerCursor función, para cambiar el cursor cuando el mouse está sobre la esquina del objeto. Dentro de la función uso la función setCursor () que en realidad toma un string como parámetro, por lo que podemos echar un vistazo aquí para los cursores: https://www.w3.org/TR/css3-ui/#cursor
fabric.Canvas.prototype._setCornerCursor = function(corner, target)
//for top left corner
if(corner == "tl")
this.setCursor(this.rotationCursor); return false;
//for top right corner
else if(corner == "tr")
this.setCursor('pointer'); return false;
//for bottom left corner
else if(corner == "bl")
this.setCursor('help'); return false;
//for bottom right corner
else if(corner == "br")
this.setCursor('copy'); return false;
;
D. Y finalmente en el mouse: hacia abajo verifico la esquina y agrego la funcionalidad canvas.on ('mouse: down', function (e) ..
La esperanza ayuda, buena suerte.
tu razonamiento es correcto. Desafortunadamente, tengo en su ejemplo "TypeError: t no está definido -> fabric.min.js: 1: 14099"
Tengo tu ejemplo un poco modificado. Anulé cuatro métodos:
- _drawControl -> icono de dibujo
- _setCornerCursor -> mostrar cursor
- _getActionFromCorner -> crear acción con el mouse hacia abajo
- _performTransformAction -> realizar una acción moviendo el mouse
var canvas = new fabric.Canvas('canvas');
var DIMICON = 15;
var HideControls =
'tl':true,
'tr':true,
'bl':true,
'br':true,
'ml':false,
'mt':false,
'mr':false,
'mb':false,
'mtr':false
;
var dataImage = [
"https://cdn1.iconfinder.com/data/icons/streamline-interface/60/cell-8-10-120.png", /*scale*/
"https://cdn1.iconfinder.com/data/icons/ui-color/512/Untitled-12-128.png", /*delete*/
"https://cdn2.iconfinder.com/data/icons/social-messaging-productivity-1/128/sync-16.png", /*rotate*/
"https://cdn2.iconfinder.com/data/icons/social-messaging-productivity-1/128/write-compose-16.png", /*change text*/
"https://cdn3.iconfinder.com/data/icons/social-messaging-productivity-1/128/save-16.png" /*save*/
];
//********override*****//
fabric.Object.prototype._drawControl = function(control, ctx, methodName, left, top) ctx.clearRect(left, top, size, size);
switch (control)
case 'tl':/*delete*/
SelectedIconImage.src = dataImage[1];
break;
case 'tr':/*scale*/
SelectedIconImage.src = dataImage[0];
break;
case 'bl':/*scale*/
SelectedIconImage.src = dataImage[0];
break;
case 'br':/*rotate*/
SelectedIconImage.src = dataImage[2];
break;
default:
ctx[methodName](left, top, size, size);
if (control == 'tl'
//override prorotype _setCornerCursor to change the corner cusrors
fabric.Canvas.prototype._setCornerCursor = function(corner, target) corner == "br")
this.setCursor('pointer');
/*ADD END*/
else
this.setCursor(this.defaultCursor);
return false;
;
fabric.Canvas.prototype._getActionFromCorner = function(target, corner)
var action = 'drag';
if (corner)
switch(corner)
case 'ml':
case 'mr':
action = 'scaleX';
break;
case 'mt':
case 'mb':
action = 'scaleY';
break;
case 'mtr':
action = 'rotate';
break;
/**ADD **/
case 'br':
action = 'rotate';
break;
case 'tl'://delete function if mouse down
action = 'delete';
canvas.remove(canvas.getActiveObject());
break;
/**ADD END**/
default: action = 'scale';
return action;
fabric.Canvas.prototype._performTransformAction = function(e, transform, pointer)
var x = pointer.x,
y = pointer.y,
target = transform.target,
action = transform.action;
if (action === 'rotate')
this._rotateObject(x, y);
this._fire('rotating', target, e);
else if (action === 'scale')
this._onScale(e, transform, x, y);
this._fire('scaling', target, e);
else if (action === 'scaleX')
this._scaleObject(x, y, 'x');
this._fire('scaling', target, e);
else if (action === 'scaleY')
this._scaleObject(x, y, 'y');
this._fire('scaling', target, e);
/**ADD**/
else if (action === 'delete')
//do nothing, because here function executed when mouse moves
/**ADD END**/
else
this._translateObject(x, y);
this._fire('moving', target, e);
this.setCursor(this.moveCursor);
//********override END*****//
//create a rect object
var rect = new fabric.Rect(
left: 100,
top: 100,
fill: "#FF0000",
stroke: "#000",
width: 100,
height: 100,
strokeWidth: 10,
opacity: .8
);
canvas.add(rect);
rect.setControlsVisibility(HideControls);
fabric.Image.fromURL('http://serio.piiym.net/CVBla/txtboard/thumb/1260285874089s.jpg', function (img)
img.top = 60;
img.left = 250;
img.setControlsVisibility(HideControls);
canvas.add(img);
);
canvas.renderAll();
No se te olvide difundir esta división si te fue de ayuda.