Adding Custom Delete (Back,toFront) Button to Controls

后端 未结 5 1791
悲哀的现实
悲哀的现实 2020-12-30 04:11

I would like to know if there is an easy way to add a delete, bring to front, bring to back function into the existing fabric.js object controls.

A

5条回答
  •  悲&欢浪女
    2020-12-30 05:00

    i believe the the solution with the dom elements is not so stable but its ok if it covers your needs, I also needed to change the default object's corner buttons , to my custom buttons for my web application. I use ,

    1. 'alter size' button, /i dont use it any more for my reasons/
    2. 'delete object' button
    3. 'edit object' button
    4. 'rotate object' button

    so you have to change 2 things in order to succeed that:

    1. change the private function '_drawControl' from fabric.js file. This is about on line 13367 (on my fabric.js). On that function fabric draws the default cornet buttons of objects and show them on seleced. We can easily change the png to our custom ones.

    below is my changed _drawControl(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. As Toon Nelissen mentioned before, i overide the fabric.Canvas.prototype.__onMouseDown function , and control my custom buttons.

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

      };

    For the rest corners we as well write the appropriate snippet(inside __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'
                }
    

    below is a screenshot of my web app's custom images

提交回复
热议问题