我目前有 http://jsfiddle.net/dgAEY/ 这完美无缺,我只需要找出一种方法来在字体太长时调整字体大小。我查看了Auto-size dynamic text to fill fixed size container,我试图应用他们发布的Jquery函数,但我无法使其工作。
HTML
<form action="" method="POST" id="nametag" class="nametag">
Line1:
<input type="text" id="line1" name="line1" style="width:250px;" /><br>
Line2:
<input type="text" id="line2" name="line2" style="width:250px;" /><br>
Line3:
<input type="text" id="line3" name="line3" style="width:250px;" /><br>
Line4:
<input type="text" id="line4" name="line4" style="width:250px;" /><br>
<br><br><b>Name Tag</b><br>
<canvas width="282px" height="177px" id="myCanvas" style="border: black thin solid;"></canvas>
</form>
的JavaScript
$(document).ready(function () {
var canvas = $('#myCanvas')[0];
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
};
imageObj.src = "http://dummyimage.com/282x177/FFF/FFF";
$('#nametag').bind('change keyup input', updateCanvas);
$('#line2').bind('click', updateCanvas);
$('#line3').bind('click', updateCanvas);
$('#line4').bind('click', updateCanvas);
function updateCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(imageObj, 0, 0);
context.textAlign = "center";
context.font = "bold 18pt Arial";
context.fillText($('#line1').val(), canvas.width * 0.5, 70);
context.font = "12pt Arial";
context.fillText($('#line2').val(), canvas.width * 0.5, 90);
context.fillText($('#line3').val(), canvas.width * 0.5, 120);
context.fillText($('#line4').val(), canvas.width * 0.5, 140);
}
});
答案 0 :(得分:15)
您可以使用context.measureText来获取当前字体中任何给定文本的像素宽度。
然后,如果宽度太大,请缩小字体大小,直到它适合。
context.font="14px verdana";
var width = context.measureText("Hello...Do I fit on the canvas?").width
if(width>myDesiredWidth) // then reduce the font size and re-measure
[添加:代码示例]
演示:http://jsfiddle.net/m1erickson/yL5jL/
这是一个do-while循环的示例,它找到适合您的文本到画布宽度的字体大小:
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
fitTextOnCanvas("Hello, World!","verdana",125);
function fitTextOnCanvas(text,fontface,yPosition){
// start with a large font size
var fontsize=300;
// lower the font size until the text fits the canvas
do{
fontsize--;
context.font=fontsize+"px "+fontface;
}while(context.measureText(text).width>canvas.width)
// draw the text
context.fillText(text,0,yPosition);
alert("A fontsize of "+fontsize+"px fits this text on the canvas");
}
答案 1 :(得分:5)
我已经创建了一个改进版的markE&#39的代码。 很明显,如果您有多个文本,他的代码会更慢。浏览器擅长缓存,但在第一次运行时,即使只有少数几行需要缩放,你也肯定会有明显的滞后。
试试这两个版本:
原始方法(markE):
http://jsfiddle.net/be6ppdre/29/
更快的方法:
http://jsfiddle.net/ho9thkvo/2/
主要代码在这里:
function fitTextOnCanvas(text, fontface){
var size = measureTextBinaryMethod(text, fontface, 0, 600, canvas.width);
return size;
}
function measureTextBinaryMethod(text, fontface, min, max, desiredWidth) {
if (max-min < 1) {
return min;
}
var test = min+((max-min)/2); //Find half interval
context.font=test+"px "+fontface;
measureTest = context.measureText(text).width;
if ( measureTest > desiredWidth) {
var found = measureTextBinaryMethod(text, fontface, min, test, desiredWidth)
} else {
var found = measureTextBinaryMethod(text, fontface, test, max, desiredWidth)
}
return found;
}
答案 2 :(得分:4)
将maxWidth
参数添加到context.textfill
$(document).ready(function () {
var canvas = $('#myCanvas')[0];
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
};
imageObj.src = "http://dummyimage.com/282x177/FFF/FFF";
$('#nametag').bind('change keyup input', updateCanvas);
$('#line2').bind('click', updateCanvas);
$('#line3').bind('click', updateCanvas);
$('#line4').bind('click', updateCanvas);
function updateCanvas() {
var maxWith = canvas.width;
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(imageObj, 0, 0);
context.textAlign = "center";
context.font = "bold 18pt Arial";
context.fillText($('#line1').val(), canvas.width * 0.5, 70, maxWith);
context.font = "12pt Arial";
context.fillText($('#line2').val(), canvas.width * 0.5, 90, maxWith);
context.fillText($('#line3').val(), canvas.width * 0.5, 120, maxWith);
context.fillText($('#line4').val(), canvas.width * 0.5, 140, maxWith);
}
});
答案 3 :(得分:2)
这只适用于一小部分情况,但如果为我提供了完美的问题答案。 fillText 的最后一个[可选]参数是 maxWidth ,所以
ctx.fillText('long text', x, y, maxWidth);
将在 x , y 处渲染“长文本”,将结果压缩为 maxWidth 。
对于非常长的文本,这会产生非常糟糕的结果,但对于超出 maxWidth 的奇数字符串,它可以是一个非常简单的上帝发送。
答案 4 :(得分:1)
针对DOM环境的简单高效的解决方案,没有循环,只需进行一次样本测量并适当地缩放结果即可。
function getFontSizeToFit(text: string, fontFace: string, maxWidth: number) {
const ctx = document.createElement('canvas').getContext('2d');
ctx.font = `1px ${fontFace}`;
return maxWidth / ctx.measureText(text).width;
}
请注意,如果在NodeJs环境中使用npm 'canvas'模块,则结果将不会那么准确,因为它们使用了一些仅返回整数样本宽度的自定义C ++实现。