You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在fabric.js 3.6.2版本中给选中框添加自定义控件?

Fabric.js 3.6.2 选中框自定义关闭控件实现方案

fabric.js 3.x版本没有v4内置的自定义控件注册API,可通过重写控件渲染逻辑、绑定交互事件实现需求,纯前端无需额外依赖。

实现步骤

  • 先保存原始的控件渲染方法,避免覆盖默认的缩放、旋转等基础控件
    // 保留原生drawControls逻辑
    const originalDrawControls = fabric.Object.prototype.drawControls;
    // 角度转弧度工具方法
    const degToRad = deg => deg * Math.PI / 180;
    
  • 重写drawControls方法,在原生控件渲染完成后额外绘制关闭按钮
    fabric.Object.prototype.drawControls = function (ctx) {
      // 先执行原生逻辑渲染默认控件
      originalDrawControls.call(this, ctx);
      // 仅元素处于选中状态、且不属于群组时展示关闭按钮
      if (!this.active || this.group) return;
    
      // 按钮自定义配置
      const btnSize = 12; // 按钮尺寸
      const offset = 8; // 按钮距离选中框右上角的偏移量
    
      // 计算按钮相对元素中心的坐标
      const btnX = (this.width / 2 + offset) * this.scaleX;
      const btnY = -(this.height / 2 + offset) * this.scaleY;
    
      ctx.save();
      // 适配元素的旋转、缩放属性
      ctx.transform(this.scaleX, 0, 0, this.scaleY, btnX, btnY);
      ctx.rotate(degToRad(this.angle));
    
      // 绘制红色关闭按钮背景
      ctx.fillStyle = '#ff4d4f';
      ctx.fillRect(-btnSize / 2, -btnSize / 2, btnSize, btnSize);
    
      // 绘制白色叉号
      ctx.strokeStyle = '#ffffff';
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.moveTo(-btnSize / 4, -btnSize / 4);
      ctx.lineTo(btnSize / 4, btnSize / 4);
      ctx.moveTo(btnSize / 4, -btnSize / 4);
      ctx.lineTo(-btnSize / 4, btnSize / 4);
      ctx.stroke();
    
      ctx.restore();
      // 存储按钮位置信息,用于后续点击判断
      this.closeBtnInfo = { x: btnX, y: btnY, size: btnSize };
    };
    
  • 绑定canvas点击事件,判断点击位置是否落在关闭按钮范围内,触发删除逻辑
    canvas.on('mouse:down', function (options) {
      const target = options.target;
      // 仅判断带有关闭按钮信息的选中元素
      if (!target || !target.closeBtnInfo) return;
    
      const pointer = canvas.getPointer(options.e);
      // 将点击坐标转换为元素本地坐标系下的坐标,适配旋转、缩放场景
      const localPoint = target.toLocalPoint(new fabric.Point(pointer.x, pointer.y), 'left', 'top');
      const btn = target.closeBtnInfo;
      const btnWidth = btn.size * target.scaleX;
      const btnHeight = btn.size * target.scaleY;
    
      // 判断点击是否在关闭按钮范围内
      if (
        localPoint.x >= btn.x - btnWidth / 2 &&
        localPoint.x <= btn.x + btnWidth / 2 &&
        localPoint.y >= btn.y - btnHeight / 2 &&
        localPoint.y <= btn.y + btnHeight / 2
      ) {
        canvas.remove(target);
        canvas.renderAll();
        options.e.preventDefault();
        options.e.stopPropagation();
      }
    });
    

可选优化

如果需要仅给特定类型元素添加关闭按钮,不需要全局重写fabric.Object.prototype.drawControls,单独重写对应类的方法即可,例如仅给矩形添加:fabric.Rect.prototype.drawControls。
按钮的尺寸、颜色、偏移量均可根据业务需求自行调整参数。

内容的提问来源于stack exchange,提问作者c00l

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:18:03