Ajouter le bouton Custom Delete (Back,toFront) aux commandes

je voudrais savoir si il existe un moyen facile d'ajouter un supprimer, de mettre au premier plan, porter à l'arrière fonction dans l'existant tissu.js contrôle des objets.

pour le moment, je ne peux cliquer que sur les boutons qui supprimeraient l'objet, mettraient à l'avant, etc.

je suis en train de trouver une solution pour être en mesure de appuyez sur X (dans le coin supérieur droit) sur l'objet et la suppression de l'objet.

je suppose qu'il aura à faire avec l'écrasement, envelopper ou sous-classer l'objet de contrôle existant.

peut-être que j'ai supervisé quelque chose et qu'il y a une solution facile? S'il vous plaît, pas de papier Div.

Fabric.js Canvas Object Selection Delete X

16
demandé sur Qantas 94 Heavy 2014-02-09 20:20:59

5 réponses

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

  • remplacer drawControls, attirer votre bouton personnalisé
  • vous devez stocker le bouton de coordonnées, de sorte que vous pouvez détecter lorsque l'utilisateur clique sur eux. C. F. _setCornerCoords et _findTargetCorner
  • incorporez votre action quelque part dans __onMouseDown

Vous n'avez pas besoin de prendre soin de "démêler" les commandes, car toute la toile est restituée lorsqu'un objet est désélectionné.

j'espère que cette aide, bonne chance :)

10
répondu Djizeus 2014-02-21 07:37:05

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();
    }


     })
5
répondu melwyn pawar 2014-04-21 12:22:29

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);
  });
})();
2
répondu Caslav Sabani 2015-10-09 09:14:27

je crois que la solution avec les éléments dom n'est pas aussi stable mais c'est ok si elle couvre vos besoins, J'ai également eu besoin de changer les boutons de coin de l'objet par défaut , à mes boutons personnalisés pour mon application web. J'utilise ,

  1. 'modifier la taille du bouton /je n'utilise pas plus pour mes raisons/
  2. "supprimer l'objet" bouton
  3. "modifier l'objet" bouton
  4. "pivoter l'objet" bouton

vous devez donc changer 2 choses pour réussir:

1. modifier la fonction privée "_drawControl" de fabric.fichier js. C'est sur la ligne 13367 (sur mon tissu.js). Sur cette fonction, fabric dessine les boutons cornet par défaut des objets et les affiche sur seleced. Nous pouvons facilement remplacer la png par nos propres png.

ci-dessous se trouve mon nouveau contrôle des courants d'air (tissu.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. Toon Nelissen mentionné avant, je surmontais le fabric.Canvas.prototype.__onMouseDown fonction, 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 le reste des coins de nous, en tant que bien inscrivez le fragment de code(à l'intérieur __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

enter image description here

2
répondu Theo Itzaris 2015-11-18 12:18:05

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

l'objet cible contient __coin de l'élément 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 });
    }
};
1
répondu Toon Nelissen 2014-09-11 18:10:50