Javascript Fabric JS/Canvas中逐行文本背景色填充

Javascript Fabric JS/Canvas中逐行文本背景色填充,javascript,canvas,html5-canvas,fabricjs,fabricjs2,Javascript,Canvas,Html5 Canvas,Fabricjs,Fabricjs2,我正在使用库FabricJS在画布上覆盖文本。我需要在包含属性textBackgroundColor的文本元素中添加padding,理想情况下是左和右 以下是我到目前为止所做的尝试: let textObject = new fabric.Text('Black & White',{ fontFamily: this.theme.font, fontSize: this.theme.size, textBaseline: 'bottom', textBac

我正在使用库FabricJS在画布上覆盖文本。我需要在包含属性textBackgroundColor的文本元素中添加padding,理想情况下是左和右

以下是我到目前为止所做的尝试:

let textObject = new fabric.Text('Black & White',{
    fontFamily: this.theme.font,
    fontSize: this.theme.size,
    textBaseline: 'bottom',
    textBackgroundColor: '#000000',
    left: 0,
    top: 0,
    width: 100,
    height: 40,
    padding: 20,
    fill: 'white',
});
填充物不像我预期的那样起作用。我尝试使用backgroundColor属性,但这会将背景添加到整个组块,而不仅仅是文本

我可以添加一个非破坏性的空间来达到同样的效果,但这似乎不是一个可靠的解决方案,我希望Fabric JS允许这一点。有什么办法可以做到这一点吗

右侧所需的解决方案版本,带有额外的填充,这是我想要的:


对于两个微妙不同的情况,我给你两个答案

案例1-在单行或多行文本的边界框周围填充。 代码遵循CSS方法,边距在框外,如红线所示,填充在框内,如金色背景所示。在左图上,黑色文本背景是您从内置的“textBackgroundColor”中获得的。当前应用的填充区域显示为黄色。右边的图片显示了当你协调填充颜色时的额外好处,同时你也可以减少背景的不透明度,同时保持文本完全不透明

顺便说一句,与控制边框相关的文本填充的内置“padding”属性,但背景色填充不覆盖创建的空白。换句话说,它的操作方式类似于CSS边距,而不是CSS填充

因此,有必要忽略这个padding属性,而是引入一个彩色rect来提供所需的背景色,将其与文本元素分组并相应地定位

下面的示例代码段

var canvas=window.u canvas=newfabric.canvas'c'; //函数进行绘图。可以很容易地容纳到一个类中,不包括画布重置! 函数resetpos { canvas.clear; //创建文本节点-注意位置为0,0 var text=new fabric.Textpos.text{ fontFamily:“Arial”, 左:0,, 排名:0, 填充:ffffff, 笔划:, textBackgroundColor:'000000' }; //创建外部“边距”矩形,注意填充和边距的位置为负偏移 //宽度的大小由文本节点的尺寸加上2 x填充+边距确定。 var rectMargin=new fabric.Rect{ 左:-1*位置填充左+位置边距左, 顶部:-1*pos.padding.top+pos.margin.top, 宽度:text.width+pos.padding.left+pos.padding.right+pos.margin.left+pos.margin.right, 高度:text.height+pos.padding.top+pos.padding.bottom+pos.margin.top+pos.margin.bottom, 冲程宽度:位置边界, 笔划:“红色”, 填充:“透明” } //创建内部“padding”矩形,注意位置仅为padding的偏移 //宽度的大小由文本节点的尺寸加上2 x填充确定。 var rectPadding=new fabric.Rect{ 宽度:text.width+pos.padding.left+pos.padding.right, 高度:text.height+pos.padding.top+pos.padding.bottom, 左:-1*pos.padding.left,top:-1*pos.padding.top, 填充:“金色” } //创建组并将形状添加到组中,首先选择矩形,使其位于文本下方。 //注意,由于组的大小过大,我们将其放置在pos-padding位置。 var group=new fabric.group[rectMargin,rectPadding,text]{ 左:位置x-位置填充左-位置边距左, 顶部:位置y-位置padding.top-位置margin.top, 角度:位置角度, }; canvas.addgroup; } //函数从用户输入中获取值 函数go { var m=$保证金'.val.split','; var p=$'padding'.val.split','; 对于变量i=0;i<4;i=i+1 { p[i]=parseIntp[i],10;//确保我们有数字而不是字符串! m[i]=parseIntm[i],10; } //对象保持位置和内容信息 var pos={x:50,y:10,text:'带填充的文本\n和另一行', 填充:{top:p[0],right:p[1],bottom:p[2],left:p[3]},边距:{top:m[0],right:m[1],bottom:m[2],left:m[3]},边框:1,角度:10}; resetpos; } //单击go按钮的处理程序 $'go'。单击,函数E{ 去 } //调用go一次以显示加载 去 div { 背景颜色:银色; 宽度:600px; 高度:300px; } .ipt { 右边距:20px; } 保证金: 衬垫: 去
对于两个微妙不同的情况,我给你两个答案

案例1-在单行或多行文本的边界框周围填充。 代码遵循CSS方法,边距在框外,如红线所示,填充在框内,如金色背景所示。在左图上,黑色文本背景是您从内置的“textBackgroundColor”中获得的。黄色区域显示当前应用的填充。右边的图片显示了当你协调填充颜色时的额外好处,同时你也可以减少背景的不透明度,同时保持色调 xt完全不透明

顺便说一句,与控制边框相关的文本填充的内置“padding”属性,但背景色填充不覆盖创建的空白。换句话说,它的操作方式类似于CSS边距,而不是CSS填充

因此,有必要忽略这个padding属性,而是引入一个彩色rect来提供所需的背景色,将其与文本元素分组并相应地定位

下面的示例代码段

var canvas=window.u canvas=newfabric.canvas'c'; //函数进行绘图。可以很容易地容纳到一个类中,不包括画布重置! 函数resetpos { canvas.clear; //创建文本节点-注意位置为0,0 var text=new fabric.Textpos.text{ fontFamily:“Arial”, 左:0,, 排名:0, 填充:ffffff, 笔划:, textBackgroundColor:'000000' }; //创建外部“边距”矩形,注意填充和边距的位置为负偏移 //宽度的大小由文本节点的尺寸加上2 x填充+边距确定。 var rectMargin=new fabric.Rect{ 左:-1*位置填充左+位置边距左, 顶部:-1*pos.padding.top+pos.margin.top, 宽度:text.width+pos.padding.left+pos.padding.right+pos.margin.left+pos.margin.right, 高度:text.height+pos.padding.top+pos.padding.bottom+pos.margin.top+pos.margin.bottom, 冲程宽度:位置边界, 笔划:“红色”, 填充:“透明” } //创建内部“padding”矩形,注意位置仅为padding的偏移 //宽度的大小由文本节点的尺寸加上2 x填充确定。 var rectPadding=new fabric.Rect{ 宽度:text.width+pos.padding.left+pos.padding.right, 高度:text.height+pos.padding.top+pos.padding.bottom, 左:-1*pos.padding.left,top:-1*pos.padding.top, 填充:“金色” } //创建组并将形状添加到组中,首先选择矩形,使其位于文本下方。 //注意,由于组的大小过大,我们将其放置在pos-padding位置。 var group=new fabric.group[rectMargin,rectPadding,text]{ 左:位置x-位置填充左-位置边距左, 顶部:位置y-位置padding.top-位置margin.top, 角度:位置角度, }; canvas.addgroup; } //函数从用户输入中获取值 函数go { var m=$保证金'.val.split','; var p=$'padding'.val.split','; 对于变量i=0;i<4;i=i+1 { p[i]=parseIntp[i],10;//确保我们有数字而不是字符串! m[i]=parseIntm[i],10; } //对象保持位置和内容信息 var pos={x:50,y:10,text:'带填充的文本\n和另一行', 填充:{top:p[0],right:p[1],bottom:p[2],left:p[3]},边距:{top:m[0],right:m[1],bottom:m[2],left:m[3]},边框:1,角度:10}; resetpos; } //单击go按钮的处理程序 $'go'。单击,函数E{ 去 } //调用go一次以显示加载 去 div { 背景颜色:银色; 宽度:600px; 高度:300px; } .ipt { 右边距:20px; } 保证金: 衬垫: 去
如果有人正在寻找使用Textbox的解决方案

以下是您可以尝试的另一种解决方案:

扩展基类并覆盖_renderBackground函数


非常简单,适合我

如果有人正在寻找使用Textbox的解决方案

以下是您可以尝试的另一种解决方案:

扩展基类并覆盖_renderBackground函数


非常简单,适合我

案例2完全符合我的要求。非常感谢您的详细解释和注释代码。非常感谢。Hello@Vanquished Wombat,我希望扩展此解决方案,以便能够使用textAlign属性left、center和right。您构建的解决方案不支持Fabric的内置对齐,因为它是一个自定义解决方案。你能帮忙吗?我很感激这不在问题的范围之内,所以我很乐意为您的时间付费。查看我的个人资料了解联系信息twitter。我们是在谈论解决方案2不支持对齐吗?是的,解决方案2。下面是一个我试图让textAlign“正确”工作的代码示例:我还需要中心对齐才能工作。如果你需要一个屏幕截图的例子,请告诉我。我按照你的方法得到了正确的中心对齐。示例:-感谢您的指导。案例2非常适合我的要求。非常感谢您的详细解释和注释代码。非常感谢。Hello@Vanquished Wombat,我希望扩展此解决方案,以便能够使用textAlign属性left、center和right。您构建的解决方案不支持Fabric的内置对齐,因为它是一个自定义解决方案。你能帮忙吗?我很感激这不在问题的范围之内,所以我很乐意为您的时间付费。查看我的个人资料了解联系信息twitter。我们是在谈论解决方案2不支持对齐吗?是的,解决方案2。下面是一个我试图让textAlign“正确”工作的代码示例:我还需要中心对齐才能工作。如果你
需要一个屏幕截图的例子,请告诉我。我按照你的方法得到了正确的中心对齐。示例:-感谢您的指导。
var TextboxWithPadding = fabric.util.createClass(fabric.Textbox, {
  _renderBackground: function(ctx) {
    if (!this.backgroundColor) {
      return;
    }
    var dim = this._getNonTransformedDimensions();
    ctx.fillStyle = this.backgroundColor;

    ctx.fillRect(
      -dim.x / 2 - this.padding,
      -dim.y / 2 - this.padding,
      dim.x + this.padding * 2,
      dim.y + this.padding * 2
    );
    // if there is background color no other shadows
    // should be casted
    this._removeShadow(ctx);
  }
});