【发布时间】:2017-08-10 10:08:51
【问题描述】:
我正在尝试计算 html 画布上文本对象的像素高度和宽度。我已经尝试了下面看到的一些代码,但我得到了错误的结果。有没有更干净的方法来计算这个?动态画布需要根据文本的长度和大小进行调整。
- px 高度和宽度需要正确计算。最左上角的像素到最右下角的像素。
- 画布需要调整大小以最小化计算时间并考虑包括“\n”在内的文本量。我试过了
canvas.setWidth(400+text.getBoundingRectWidth()); canvas.setHeight(400+text.getBoundingRectHeight());
但我不确定它是否有效。
我如何重写此代码以使画布大小是动态的并根据可以更改的文本进行调整(例如,在文本区域中写文章的人)?
如何正确计算文本的大小?
如果有人重写此代码以正确满足我的上述规范,我可以提供奖励(金钱、礼品卡、免费披萨等...)。我已经花了很多时间试图弄清楚这一点。
研究: Calculate bounding box of arbitrary pixel-based drawing 看起来很有希望。
这里是 JSBIN(基于 Fabric.js: Get text bounding box width and height) http://jsbin.com/zoqolik/3/edit?html,css,js,console,output
fabric.Object.prototype.objectCaching = false;
var txt = '\n'+'Adklfmask'+'\n'+'asdfsd'+'\n'+'asdfsd'+'\n'+'asdfsd'+"\n";
var canvas = new fabric.Canvas('canvas');
var text = new fabric.IText(txt, {
left: 200,
top: 200,
fontFamily: 'Princess Sofia',
padding: 5,
fontSize: 35,
lineHeight: 2.5,
textAlign: 'center'
});
canvas.add(text);
canvas.renderAll();
var ctx = canvas.getContext();
var hei = Math.ceil(300+text.getBoundingRectHeight());
var wid = Math.ceil(300+text.getBoundingRectWidth());
function setWidth(width) {
var canvas = document.getElementById("canvas");
canvas.width = width;
}
function setHeight(height) {
var canvas = document.getElementById("canvas");
canvas.height = height;
}
canvas.setWidth(400+text.getBoundingRectWidth());
canvas.setHeight(400+text.getBoundingRectHeight());
// get/draw bounding box
var bbox = getBoundingBox(ctx, 0, 0, wid, hei);
console.log(bbox.width + ' x ' + bbox.height);
drawBoundingBox(ctx, bbox);
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('right', c);
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;
}
【问题讨论】:
-
您可以使用
ctx.getImageData来锻炼某些文本的范围。在屏幕外的画布上渲染您想要的文本,获取所有像素,然后通过检查空行和空列找到顶部、底部、左侧和右侧(所有 alpha 值都为零) 不是很快,但如果您在开始时执行每个字符只需记录顶部和底部,然后您可以使用测量文本来获取宽度并查找字符以找到最大垂直范围。
标签: javascript html canvas html5-canvas fabricjs