Javascript 向控件添加自定义删除(后退、后退)按钮

Javascript 向控件添加自定义删除(后退、后退)按钮,javascript,html,canvas,html5-canvas,fabricjs,Javascript,Html,Canvas,Html5 Canvas,Fabricjs,我想知道是否有一个简单的方法来添加删除,带到前面,带到后面 函数插入现有的fabric.js对象控件中 目前,我只能点击按钮,删除对象,带到前面等 我正在寻找一个解决方案,以便能够按对象上的X(右上角)并删除该对象。 我想这与覆盖、包装或子类化现有控件对象有关 也许我监督了一些事情,有一个简单的解决办法?请不要用Div包装纸 Fabric.js不提供任何向对象添加控件的简单方法。 如果要创建自己的控件,必须覆盖对象类,特别是: 覆盖drawControls,以绘制自定义按钮 您需要存储按钮的坐

我想知道是否有一个简单的方法来添加删除,带到前面,带到后面 函数插入现有的fabric.js对象控件中

目前,我只能点击按钮,删除对象,带到前面等

我正在寻找一个解决方案,以便能够按对象上的X(右上角)并删除该对象。

我想这与覆盖、包装或子类化现有控件对象有关

也许我监督了一些事情,有一个简单的解决办法?请不要用Div包装纸


Fabric.js不提供任何向对象添加控件的简单方法。 如果要创建自己的控件,必须覆盖对象类,特别是:

  • 覆盖
    drawControls
    ,以绘制自定义按钮
  • 您需要存储按钮的坐标,以便在用户单击按钮时进行检测。C.f.
    \u setCornerCoords
    \u findTargetCorner
  • 将您的操作合并到
    \u onMouseDown
您不需要“取消绘制”控件,因为当取消选择对象时,整个画布将重新渲染


我希望这有帮助,祝你好运:)

我已经通过定位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();
    }


     })
canvas.on('object:selected',函数(e){
jQuery(“.deleteBtn”).remove();
var btnLeft=e.target.oCoords.mt.x;
var btnTop=e.target.OCORDS.mt.y-25;
var widthadjust=e.target.width/2;
btnLeft=宽度调整+btnLeft-10;
var deleteBtn='✕;

'; jQuery(“.canvas容器”).append(deleteBtn); //.canvas容器是相对于通过CSS定位的画布的父div }); //删除按钮单击事件 jQuery(document).on('click',.deleteBtn',function()){ if(canvas.getActiveObject()) { 移除(canvas.getActiveObject()); //这将删除舞台上当前活动的对象, jQuery(this.remove(); jQuery(“.deleteBtn”).remove(); } })
您可以像下面这样覆盖uu onMouseDown函数

目标对象包含\uuu corner元素
target.\uu corner

检查这是否为“tr”(右上)并删除activeObject

    if (target.__corner === 'tr') {
        if(canvas.getActiveObject()){
            canvas.remove(canvas.getActiveObject());
        }
    }
完整代码:

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

您可以尝试使用html按钮。看看这个例子:

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

下面是代码示例:

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

我相信使用dom元素的解决方案不太稳定,但如果它满足您的需要,就可以了, 我还需要将默认对象的角按钮更改为web应用程序的自定义按钮。 我用

  • “更改大小”按钮,/出于我的原因,我不再使用它/
  • “删除对象”按钮
  • “编辑对象”按钮
  • “旋转对象”按钮
  • 因此,为了成功,你必须改变两件事:

    1。从fabric.js文件更改私有函数“\u drawControl”。这是关于第13367行(在我的fabric.js上)。在该函数上,fabric绘制对象的默认cornet按钮,并在seleced上显示它们。 我们可以很容易地将png更改为自定义的

    下面是我更改的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;
                    }
                  }
    
    
            }
      },
    
  • 正如前面提到的Toon Nelissen一样,我覆盖了
    fabric.Canvas.prototype.\u onMouseDown
    功能,并控制我的自定义按钮

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

  • 对于其余的角落,我们还可以编写相应的代码片段(在_onMouseDown内):

    下面是我的web应用程序的自定义图像截图


    所以我想这是我们能得到的最接近的了我在
    object\u interactivity.mixin.js
    中看到了
    drawControls
    。我会调查一下。如果没有其他答案,你就会得到赏金。@zer02,你有什么解决办法吗?我也想实现类似的东西。请检查与上述实现的代码相同的解决方案,我在我的画布应用。一切正常,但当用户旋转图像时,
    delete
    图像无法放置在正确的位置。我可以知道当用户旋转时我应该尝试添加什么删除图像吗?它不是我的,所以我不能删除它,对不起