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