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

Fabric.js中自定义形状的圆角无法更新问题

Fabric.js中自定义形状的圆角无法更新问题

嘿,我猜你现在应该是碰到了自定义圆角矩形的圆角值更新后,画布上的形状没跟着变化的问题吧?我之前在Fabric.js里自定义形状的时候也踩过这个坑,给你梳理下问题原因和解决办法~

首先,先把你没写完的_render方法补全(这部分是绘制不同圆角的核心逻辑),然后重点解决属性更新不触发重绘的关键问题:

Fabric.js的自定义对象,如果你新增了自己的属性(比如你的topLeft、topRight这些独立圆角参数),必须把它们加入到stateProperties数组里,不然Fabric不会监听这些属性的变化,自然也就不会自动触发重绘。另外,还要重写toObject方法,确保这些自定义属性能被序列化(比如保存画布的时候不会丢失这些圆角设置)。

下面是修正后的完整自定义类代码:

fabric.RoundedRect = fabric.util.createClass(fabric.Rect, {
  type: 'roundedRect',
  
  // 把自定义属性加入stateProperties,让Fabric监听变化
  stateProperties: fabric.Rect.prototype.stateProperties.concat(['topLeft', 'topRight', 'bottomLeft', 'bottomRight']),

  initialize: function (options) {
    options = options || {};
    this.callSuper('initialize', options);
    this.set('topLeft', options.topLeft || [20, 20]);
    this.set('topRight', options.topRight || [20, 20]);
    this.set('bottomLeft', options.bottomLeft || [20, 20]);
    this.set('bottomRight', options.bottomRight || [20, 20]);
  },

  // 重写toObject,确保自定义属性被序列化
  toObject: function() {
    return fabric.util.object.extend(this.callSuper('toObject'), {
      topLeft: this.topLeft,
      topRight: this.topRight,
      bottomLeft: this.bottomLeft,
      bottomRight: this.bottomRight
    });
  },

  _render: function (ctx) {
    var w = this.width,
        h = this.height,
        x = -this.width / 2,
        y = -this.height / 2,
        // 贝塞尔曲线近似圆弧的系数
        k = 1 - 0.5522847498;

    ctx.beginPath();

    // 左上角圆角
    ctx.moveTo(x + this.topLeft[0], y);
    ctx.bezierCurveTo(
      x + this.topLeft[0] * k, y,
      x, y + this.topLeft[1] * k,
      x, y + this.topLeft[1]
    );

    // 左下角圆角
    ctx.lineTo(x, y + h - this.bottomLeft[1]);
    ctx.bezierCurveTo(
      x, y + h - this.bottomLeft[1] * k,
      x + this.bottomLeft[0] * k, y + h,
      x + this.bottomLeft[0], y + h
    );

    // 右下角圆角
    ctx.lineTo(x + w - this.bottomRight[0], y + h);
    ctx.bezierCurveTo(
      x + w - this.bottomRight[0] * k, y + h,
      x + w, y + h - this.bottomRight[1] * k,
      x + w, y + h - this.bottomRight[1]
    );

    // 右上角圆角
    ctx.lineTo(x + w, y + this.topRight[1]);
    ctx.bezierCurveTo(
      x + w, y + this.topRight[1] * k,
      x + w - this.topRight[0] * k, y,
      x + w - this.topRight[0], y
    );

    ctx.closePath();
    this._renderFill(ctx);
    this._renderStroke(ctx);
  }
});

再给你提个Vue里的使用小注意点:

  • 当你需要修改某个圆角值的时候,一定要用Fabric的set方法,而不是直接修改属性,比如:
    // 正确的方式
    roundedRect.set('topLeft', [50, 50]);
    // 若Fabric未自动触发重绘,手动调用这句
    canvas.renderAll();
    
  • 直接写roundedRect.topLeft = [50,50]是不行的,因为Fabric不会监听这种直接赋值的变化。

这样修改后,你更新圆角参数的时候,画布上的形状就会跟着重新绘制啦~

备注:内容来源于stack exchange,提问作者arn baig

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 11:03:00