简体   繁体   English

Fabric.js:获取文本边界框的宽度和高度

[英]Fabric.js: Get text bounding box width and height

I'm using fabric.js. 我正在使用fabric.js。 I would like to get the dimensions of the rectangle (is "bounding box" the correct term?) that exactly contains the text (represented by the red box below). 我想得到矩形的尺寸(是“边界框”正确的术语?),它确切地包含文本(由下面的红框表示)。 The default fabric.js box has padding even if I change padding to 0. 即使我将填充更改为0,默认的fabric.js框也有填充。

在此输入图像描述

I tried to get the context from the fabric canvas and then call .measureText() but it didn't give the full information I needed for a bounding box. 我试图从结构画布中获取上下文然后调用.measureText()但它没有提供我需要的边界框的完整信息。

EDIT: 编辑:

It seems there are several components of the IText object: the container, the selection area, and the text itself. 似乎IText对象有几个组件:容器,选择区域和文本本身。 In the image below, the IText box is the light blue line. 在下图中,IText框是浅蓝色线。 The selection area is the light blue fill. 选择区域是浅蓝色填充。 The red box is what I need ....it's the area that exactly contains the text itself ( not even 1 pixel between such a rectangle and the most extreme parts of the text). 红色框是我需要的 ......它是完全包含文本本身的区域(在这样的矩形和文本的最极端部分之间甚至不是1个像素 )。 The methods getBoundingRectHeight and getBoundingRectWidth (both deprecated and replaced by getBoundingRect I believe) return the height/width of the outer IText container box (light blue line). 方法getBoundingRectHeight和getBoundingRectWidth(我不相信,不推荐使用getBoundingRect代替)返回外部IText容器框的高度/宽度(浅蓝色线条)。

在此输入图像描述

Note: this is an 8 px padded box (the area between the blue line and blue fill). 注意:这是一个8 px填充框(蓝线和蓝色填充之间的区域)。 Even if I make padding 0, the functions still don't give me what I need. 即使我填充0,功能仍然不能满足我的需要。

您是否尝试过在每个结构对象上使用getBoundingRectHeight()getBoundingRectWidth()方法?

I have no idea about the performance or resources that are used to do this. 我不知道用于执行此操作的性能或资源。 But it does work. 但它确实有效。 Thanks to @Prestaul's post for a getting me started. 感谢@ Prestaul的帖子让我开始。 This is what I came up with: 这就是我想出的:

function getBoundingBox(ctx, left, top, width, height) {
    var ret = {};

    // Get the pixel data from the canvas
    var data = ctx.getImageData(left, top, width, height).data;
    console.log(data);
    var first = false; 
    var last = false;
    var right = false;
    var left = false;
    var r = height;
    var w = 0;
    var c = 0;
    var d = 0;

    // 1. get bottom
    while(!last && r) {
        r--;
        for(c = 0; c < width; c++) {
            if(data[r * width * 4 + c * 4 + 3]) {
                console.log('last', r);
                last = r+1;
                ret.bottom = r+1;
                break;
            }
        }
    }

    // 2. get top
    r = 0;
    var checks = [];
    while(!first && r < last) {

        for(c = 0; c < width; c++) {
            if(data[r * width * 4 + c * 4 + 3]) {
                console.log('first', r);
                first = r-1;
                ret.top = r-1;
                ret.height = last - first - 1;
                break;
            }
        }
        r++;
    }

    // 3. get right
    c = width;
    while(!right && c) {
        c--;
        for(r = 0; r < height; r++) {
            if(data[r * width * 4 + c * 4 + 3]) {
                console.log('last', r);
                right = c+1;
                ret.right = c+1;
                break;
            }
        }
    }

    // 4. get left
    c = 0;
    while(!left && c < right) {

        for(r = 0; r < height; r++) {
            if(data[r * width * 4 + c * 4 + 3]) {
                console.log('left', c-1);
                left = c;
                ret.left = c;
                ret.width = right - left - 1;
                break;
            }
        }
        c++;

        // If we've got it then return the height
        if(left) {
            return ret;    
        }
    }

    // We screwed something up...  What do you expect from free code?
    return false;
}

And here's a jsfiddle demo: http://jsfiddle.net/spencerw/j41jx0e2/ 这是一个jsfiddle演示: http//jsfiddle.net/spencerw/j41jx0e2/

The following is an excerpt from "HTML Canvas 2D Context, Editor's Draft 13 November 2014" of W3C. 以下是W3C的“HTML Canvas 2D Context,编辑草案2014年11月13日草案”的摘录。 It's a note from the chapter on drawing text: 这是关于绘图文本章节的一个注释:

Glyphs rendered using fillText() and strokeText() can spill out of the box given by the font size (the em square size) and the width returned by measureText() (the text width). 使用fillText()和strokeText()渲染的字形可以溢出由字体大小(em方形大小)和measureText()返回的宽度(文本宽度)给出的框。 This version of the specification does not provide a way to obtain the bounding box dimensions of the text. 此版本的规范未提供获取文本的边界框尺寸的方法。 If the text is to be rendered and removed, care needs to be taken to replace the entire area of the canvas that the clipping region covers, not just the box given by the em square height and measured text width. 如果要渲染和删除文本,则需要注意替换剪切区域覆盖的画布的整个区域,而不仅仅是由em方形高度和测量文本宽度给出的框。

Currently, it seems you cannot determine a bounding box from javascript like you need. 目前,您似乎无法根据需要确定javascript的边界框。 You can only rely on redrawing the whole canvas / clipping region. 您只能依赖重绘整个画布/剪裁区域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM