如何在famo.us中获取文本边界框

时间:2014-06-30 17:34:03

标签: text famo.us

我正在尝试绘制一个SVG bezier曲线,该曲线从Surface中文本字符串的末尾开始。我可以将Surface的大小设置为[true,true],这应该使大小等于文本边界框。但如果我稍后尝试" mySurface.size [0]"为了获得宽度,它返回" true"!我需要为该边界框的宽度和高度得到一个数字,以便计算我的贝塞尔曲线的终点!等效的DOM方法只是使用.getBBox()函数..我该如何在Famo.us中这样做?

4 个答案:

答案 0 :(得分:0)

这可能是因为表面还没有渲染。这里有一些类似的问题,其中一个来自我: how can we get the size of a surface within famo.us?

您也可以尝试延迟或使用setTimeout或Engine.nextTick()来检查下一个循环的大小。

如果你找到一个优雅的解决方案让我们知道,因为这是一个很大的问题,在许多地方使用着名的 - 必须做多个高分辨率,你不能真正定位场景的初始设置 - 你必须让它渲染然后调整......

答案 1 :(得分:0)

你可以使用'getSize'函数并指定'true'来获得曲面的实际大小:

var realSize = surface.getSize(true);

答案 2 :(得分:0)

@ljzerenHein,感谢提示..不幸的是,surface.getSize(true)返回null!
@dcsan,谢谢你的链接。我相信你可能是对的,不过与之相关的解决方案对我来说太过牵扯。

经过大量搜索,黑客攻击和实验,我已经采取了以下方法: - ]使用DOM获取文本字符串的未转换边界框
- ]格式化SVG格式的文本字符串
- ]使字符串不可见(将填充和笔划设置为无) - ]重复使用相同的" div"我要测量的所有字符串的元素
- ]一旦我有了未转换的边界框,然后将着名的表面尺寸设置为该尺寸,然后应用修改器 - ]如果在应用了所有变换后我需要边界框,则获取曲面的总累积变换并将其与原始未变换的边界框相乘

这里是创建DOM元素的代码,插入SVG文本,然后获取边界框:

//Do this part once, of creating a DOM element and adding it to the document
var el1 =  document.createElement("div");
document.body.appendChild(el1); //only need to append once -- just set innerHTML after

//now set the SVG text string -- from this point down can be repeated for multiple
// strings without removing or re-adding the element, nor fiddling with the DOM
var text1_1_1_SVG = '<svg>  <text x="0" y="0" style="font-family: Arial; font-size: 12;fill:none;stroke:none" id="svgText1">' + myFamousSurface.content + '</text> </svg>';
//note the id is inside the text element! Also the fill and stroke are null so nothing paints
el1.innerHTML = text1_1_1_SVG; 

//now get the element -- this seems to be what triggers the bounding box calc
var test = document.getElementById("svgText1"); //this is ID in the text element

//get the box, take the values out of it, and display them
var rect = test.getBoundingClientRect();
var str = "";
for (i in rect) { //a trick for getting all the attributes of the object
    str += i + " = " + rect[i] + "  ";
}
console.log("svgText1: " + str);

仅供参考,所有SVGTextElement方法似乎都可以在gotElem上调用 SVGTextElement文档在这里:http://msdn.microsoft.com/en-us/library/ie/ff972126(v=vs.85).aspx

答案 3 :(得分:0)

@seanhalle

我很确定.getSize(true)返回null,因为该元素尚未添加到DOM中。请记住,famo.us与动画帧同步,并且发生对DOM的更新不会立即发生。直接访问DOM(也就是ping)是非常不受欢迎的,因为你将失去famo.us承诺的性能优势。

我要做的是创建一个自定义视图来包裹你的表面并在其中实现一个render方法。在render-method中,使用getSize(true)来获取大小。如果返回null, 你知道它还没有被提交给DOM。

<强> view in action as jsfiddle

define('MyView', function (require, exports, module) {
    var View = require('famous/core/View');
    var Surface = require('famous/core/Surface');
    function MyView() {
        View.apply(this, arguments);
        this.surface = new Surface();
        this.add(this.surface);
    }
    MyView.prototype = Object.create(View.prototype);
    MyView.prototype.constructor = MyView;

    MyView.prototype.render = function() {
        var size = this.getSize(true);
        if (size) {
            if (!this.hasSize) {
                this.hasSize = true;
                console.log('now we have a size: ' + size);
            }
            this.surface.setContent('Size: ' + JSON.stringify(size));
        } else {
            console.log('no size yet');
        }
        return this._node.render();
    };

    module.exports = MyView;
});