Ajout d'un bouton Supprimer personnalisé (Retour, vers le bas) aux contrôles

J'aimerais savoir s'il existe un moyen simple d'ajouter une suppression, d'amener à l'avant, de renvoyer la fonction dans les contrôles existants de l'objet fabric.js .

Pour le moment, je ne peux que cliquer sur les boutons qui suppriment l'objet, le faire avancer, etc.

Je travaille sur la recherche d'une solution pour pouvoir appuyer sur X (dans le coin supérieur droit) sur l'objet et supprimer l'objet.

Je suppose qu'il faudra écraser, envelopper ou sous-classer l'objet de contrôle existant.

Peut-être que j'ai surveillé quelque chose et il y a une solution facile? S'il vous plaît, pas d'emballage Div.

Fabric.js Canvas Object Selection Supprimer X

Fabric.js n'offre aucun moyen simple d'ajouter des contrôles aux objets. Si vous souhaitez créer vos propres contrôles, vous devrez écraser la classe Object, notamment:

  • drawControls , pour dessiner votre bouton personnalisé
  • Vous devrez stocker les coordonnées du bouton, afin que vous puissiez détecter quand l'utilisateur clique. Cf _setCornerCoords et _findTargetCorner
  • Incorporez votre action quelque part dans __onMouseDown

Vous n'avez pas besoin de prendre soin de «dévisser» les contrôles, car la totalité de la toile est redessinée lorsqu'un objet est désélectionné.

J'espère que ça aide et bonne chance 🙂

Je l'ai implémenté via le positionnement d'un élément html

 canvas.on('object:selected',function(e){ jQuery(".deleteBtn").remove(); var btnLeft = e.target.oCoords.mt.x; var btnTop = e.target.oCoords.mt.y - 25; var widthadjust=e.target.width/2; btnLeft=widthadjust+btnLeft-10; var deleteBtn = '<p" class="deleteBtn" title="Delete" style="position:absolute;top:'+btnTop+'px;left:'+btnLeft+'px;cursor:pointer;" title="Remove object">&#10005;</p>'; jQuery(".canvas-container").append(deleteBtn); //.canvas-container is the parent div to the canvas positioned relative via CSS }); canvas.on('mouse:down',function(e){ if(canvas.getActiveObject()) { } else { jQuery(".deleteBtn").remove(); } }); canvas.on('object:modified',function(e){ jQuery(".deleteBtn").remove(); var btnLeft = e.target.oCoords.mt.x; var btnTop = e.target.oCoords.mt.y - 25; var widthadjust=e.target.width/2; btnLeft=widthadjust+btnLeft-10; var deleteBtn = '<p" class="deleteBtn" title="Delete" style="position:absolute;top:'+btnTop+'px;left:'+btnLeft+'px;cursor:pointer;" title="Remove object">&#10005;</p>'; jQuery(".canvas-container").append(deleteBtn); //.canvas-container is the parent div to the canvas positioned relative via CSS }); //THE DELETE BUTTON CLICK EVENT jQuery(document).on('click',".deleteBtn",function(){ if(canvas.getActiveObject()) { canvas.remove(canvas.getActiveObject()); //this would remove the currently active object on stage, jQuery(this).remove(); jQuery(".deleteBtn").remove(); } }) 

Je crois que la solution avec les éléments dom n'est pas si stable, mais c'est correcte si elle couvre vos besoins, j'ai également besoin de changer les boutons d'angle de l'objet par défaut, à mes boutons personnalisés pour mon application Web. J'utilise ,

  1. Bouton "modifier la taille" / je ne l'utilise plus pour mes raisons /
  2. Bouton 'Supprimer l'objet'
  3. Bouton "Editer objet"
  4. Bouton 'Rotate Object'

Donc il faut changer 2 choses pour réussir:

1. changez la fonction privée '_drawControl' du fichier fabric.js. Il s'agit de la ligne 13367 (sur mon tissu.js). Sur cette fonction, le dessin dessine les boutons de cornet par défaut et les montre sur sélection. Nous pouvons facilement changer le png à nos personnalisés.

Ci-dessous est mon _drawControl modifié (fabric.js):

  _drawControl: function(control, ctx, methodName, left, top, flipiX, flipiY) { var sizeX = this.cornerSize / this.scaleX, sizeY = this.cornerSize / this.scaleY; if (this.isControlVisible(control)) { isVML || this.transparentCorners || ctx.clearRect(left, top, sizeX, sizeY); var SelectedIconImage = new Image(); var lx=''; var ly=''; var n=''; switch (control) { case 'tl': if (flipiY) { ly='b'; } else { ly = 't'; } if (flipiX) { lx='r'; } else { lx = 'l'; } break; case 'tr': if (flipiY) { ly='b'; } else { ly = 't'; } if (flipiX) { lx='l'; } else { lx = 'r'; } break; case 'bl': if (flipiY) { ly='t'; } else { ly = 'b'; } if (flipiX) { lx='r'; } else { lx = 'l'; } break; case 'br': if (flipiY) { ly='t'; } else { ly = 'b'; } if (flipiX) { lx='l'; } else { lx = 'r'; } break; default: ly=control.substr(0, 1); lx=control.substr(1, 1); break; } control=ly+lx; switch (control) { case 'tl': //my custom png for the object's top left corner SelectedIconImage.src = 'assets/img/icons/draw_control/icon_rotate.png'; break; case 'tr': if (flipiX && !flipiY) { n='2'; } if (!flipiX && flipiY) { n='3'; } if (flipiX && flipiY) { n='4'; } //my custom png for the object's top right corner SelectedIconImage.src = 'assets/img/icons/draw_control/icon_delete.png'; break; case 'mt': SelectedIconImage.src = //add your png here if you want middle top custom image; break; case 'bl': if (flipiY) { n='2'; } SelectedIconImage.src = //add your png here if you want bottom left corner custom image; break; case 'br': if (flipiX || flipiY) { n='2'; } if (flipiX && flipiY) { n=''; } //my custom png for the object's bottom right corner SelectedIconImage.src = 'assets/img/icons/draw_control/icon_settings.png'; break; case 'mb': SelectedIconImage.src = //middle bottom png here ; break; case 'ml': SelectedIconImage.src = 'assets/img/icons/draw_control/icono_escala_horizontal'+n+'.jpg'; break; case 'mr': SelectedIconImage.src = //middle right png here; break; default: ctx[methodName](left, top, sizeX, sizeY); break; } // keep middle buttons size fixed if (control == 'tl' || control == 'tr' || control == 'bl' || control == 'br' || control == 'mt' || control == 'mb' || control == 'ml' || control == 'mr') { sizeX = 19; sizeY = 19; ctx.drawImage(SelectedIconImage, left, top, sizeX, sizeY); } try { ctx.drawImage(SelectedIconImage, left, top, sizeX, sizeY); } catch (e) { if (e.name != "NS_ERROR_NOT_AVAILABLE") { throw e; } } } }, 
  1. Comme Toon Nelissen l'a mentionné précédemment, je dépasse le fabric.Canvas.prototype.__onMouseDown fonction fabric.Canvas.prototype.__onMouseDown et contrôle mes boutons personnalisés.

     fabric.Canvas.prototype.__onMouseDown = function (e) { // accept only left clicks var isLeftClick = 'which' in e ? e.which === 1 : e.button === 1; if (!isLeftClick && !fabric.isTouchSupported) { return; } if (this.isDrawingMode) { this._onMouseDownInDrawingMode(e); return; } // ignore if some object is being transformed at this moment if (this._currentTransform) { return; } var target = this.findTarget(e), pointer = this.getPointer(e, true); //if user clicked on the top right corner image if (target && target.__corner === 'tr') { //my code goes here } } else { // save pointer for check in __onMouseUp event this._previousPointer = pointer; var shouldRender = this._shouldRender(target, pointer), shouldGroup = this._shouldGroup(e, target); if (this._shouldClearSelection(e, target)) { this._clearSelection(e, target, pointer); } else if (shouldGroup) { this._handleGrouping(e, target); target = this.getActiveGroup(); } if (target && target.selectable && !shouldGroup) { this._beforeTransform(e, target); this._setupCurrentTransform(e, target); } // we must renderAll so that active image is placed on the top canvas shouldRender && this.renderAll(); this.fire('mouse:down', { target: target, e: e }); target && target.fire('mousedown', { e: e }); } 

    };

Pour les autres coins, nous écrivons également l'extrait approprié (à l'intérieur de __onMouseDown):

  //if user clicked on the bottom right corner image if (target && target.__corner === 'br') { //my code here }else{ //the same as 'tr' } //if user clicked on the top left corner image if (target && target.__corner === 'tl') { //my code here }else{ //the same as 'tr' } //if user clicked on the bottom left corner image if (target && target.__corner === 'bl') { //my code here }else{ //the same as 'tr' } 

Ci-dessous est une capture d'écran des images personnalisées de mon application Web

Entrez la description de l'image ici

Vous pouvez écraser la fonction __onMouseDown par exemple comme ceci.

L'objet cible contient __corner element target.__corner

Vérifiez si c'est 'tr' (en haut à droite) et supprimez ActiveObject

  if (target.__corner === 'tr') { if(canvas.getActiveObject()){ canvas.remove(canvas.getActiveObject()); } } 

Code complet:

 fabric.Canvas.prototype.__onMouseDown = function (e) { // accept only left clicks var isLeftClick = 'which' in e ? e.which === 1 : e.button === 1; if (!isLeftClick && !fabric.isTouchSupported) { return; } if (this.isDrawingMode) { this._onMouseDownInDrawingMode(e); return; } // ignore if some object is being transformed at this moment if (this._currentTransform) { return; } var target = this.findTarget(e), pointer = this.getPointer(e, true); if (target && target.__corner === 'tr') { if(this.getActiveObject()){ this.remove(this.getActiveObject()); } } else { // save pointer for check in __onMouseUp event this._previousPointer = pointer; var shouldRender = this._shouldRender(target, pointer), shouldGroup = this._shouldGroup(e, target); if (this._shouldClearSelection(e, target)) { this._clearSelection(e, target, pointer); } else if (shouldGroup) { this._handleGrouping(e, target); target = this.getActiveGroup(); } if (target && target.selectable && !shouldGroup) { this._beforeTransform(e, target); this._setupCurrentTransform(e, target); } // we must renderAll so that active image is placed on the top canvas shouldRender && this.renderAll(); this.fire('mouse:down', { target: target, e: e }); target && target.fire('mousedown', { e: e }); } }; 

Vous pouvez essayer avec les boutons html. Regardez l'exemple:

http://fabricjs.com/interaction-with-objects-outside-canvas/

Voici l'exemple de code:

  (function() { var canvas = this.__canvas = new fabric.Canvas('c'); fabric.Object.prototype.transparentCorners = false; fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center'; fabric.Canvas.prototype.getAbsoluteCoords = function(object) { return { left: object.left + this._offset.left, top: object.top + this._offset.top }; } var btn = document.getElementById('inline-btn'), btnWidth = 85, btnHeight = 18; function positionBtn(obj) { var absCoords = canvas.getAbsoluteCoords(obj); btn.style.left = (absCoords.left - btnWidth / 2) + 'px'; btn.style.top = (absCoords.top - btnHeight / 2) + 'px'; } fabric.Image.fromURL('../lib/pug.jpg', function(img) { canvas.add(img.set({ left: 250, top: 250, angle: 30 }).scale(0.25)); img.on('moving', function() { positionBtn(img) }); positionBtn(img); }); })();