我遇到的问题是保持用户输入的文本在canvas元素中垂直居中。我已经构建了一个测试环境来尝试解决这个问题,我在这篇文章中提供了一个小提琴。这是我的代码:
HTML:
Enter Your Text: <br/>
<textarea id="inputtextuser" onkeyup="inputtextgo()" name="Text">Enter Your</textarea> <br/>
TextBaseline:
<select id="inputtextbaseline" onchange="inputtextgo()";>
<option value="alphabetic">alphabetic</option>
<option value="top">top</option>
<option value="bottom">bottom</option>
<option value="middle">middle</option>
<option value="hanging">hanging</option>
</select> <br/>
<canvas id="canvas1" width="300px" height="200px" >Your browser does not support the HTML5 canvas tag.</canvas> <br/>
<div id ="textheightentered"></div>
CSS:
canvas {
border: solid 1px black;
}
的JavaScript / jQuery的:
//Declaring the Canvas
var canvas1 = document.getElementById('canvas1');
context1 = canvas1.getContext('2d');
//running the function to update the canvas
inputtextgo();
function inputtextgo() {
//Retrieving the text entered by the user
var inputtext = document.getElementById("inputtextuser").value;
//Calling the function to calculate the height on the text entered by the user
var textheight = fontheight(inputtext);
//retrieving the baseline selected by the user
var baseline = document.getElementById("inputtextbaseline").value;
//calculating the new y needed to center the text based on the height of the text
var y = 100 + textheight/2;
//Updating the canvas for the new text entered by the user
context1.clearRect(0, 0, 300, 200);
context1.font = "36px arial";
context1.textBaseline = baseline;
context1.fillText (inputtext, 0, y);
//Drawing a line across the middle of the canvas for reference
context1.strokeStyle="red";
context1.moveTo(5,100);
context1.lineTo(290,100);
context1.stroke();
$("#textheightentered").text("Text Height: " + textheight);
}
function fontheight(text){
var canvas=document.createElement("canvas");
canvas.width = 1000;
canvas.height = 200;
var ctx=canvas.getContext("2d");
function measureTextHeight(left, top, width, height,text) {
// Draw the text in the specified area
ctx.save();
ctx.clearRect(0,0, canvas.width, canvas.height);
ctx.baseline = "top";
ctx.fillText(text, 0, 35); // This seems like tall text... Doesn't it?
ctx.restore();
// Get the pixel data from the canvas
var data = ctx.getImageData(left, top, width, height).data,
first = false,
last = false,
r = height,
c = 0;
// Find the last line with a non-white pixel
while(!last && r) {
r--;
for(c = 0; c < width; c++) {
if(data[r * width * 4 + c * 4 + 3]) {
last = r;
break;
}
}
}
// Find the first line with a non-white pixel
while(r) {
r--;
for(c = 0; c < width; c++) {
if(data[r * width * 4 + c * 4 + 3]) {
first = r;
break;
}
}
// If we've got it then return the height
if(first != r) return last - first;
}
// We screwed something up... What do you expect from free code?
return 0;
}
ctx.font= "36px arial";
var height = measureTextHeight(0, 0, canvas.width, canvas.height,text);
//return the height of the string
return height;
} // end $(function(){});
JSFiddle:http://jsfiddle.net/grapien/R6DWN/3/
我遇到的问题是,如果用户输入小写“y”,例如文本高度发生变化,文本不会保留在画布的中心。这是因为y变量中执行的基线校正需要根据输入的文本(小写和大写字符的组合)而不同,因为基线下方的文本偏移了y变量中执行的校正。
这就是我遇到问题的地方,因为我希望在canvas元素中始终保持文本居中。我唯一能想到的是计算textbaseline参考点下方的非空白像素。然后使用从基线到文本末尾的差异来偏移文本以使其在画布上居中。我不确定你是如何编写这个脚本的,或者甚至可能。但这是我提出的最佳方法。
如果有人有任何想法或指导,我们将不胜感激,因为开发解决这个问题的方法让我感到难过。
答案 0 :(得分:1)
我相信我已经使用我在问题中所述的技术解决了这个问题。我创建了一个新函数,用于计算延伸到输入文本基线以下的字体数量。使用与用于计算高度的类似技术。我使用字母基线然后计算包含高于此基线的内容的像素。请参阅下面的功能。
function fontheight2(text){
var canvas=document.createElement("canvas");
canvas.width = 1000;
canvas.height = 200;
var ctx=canvas.getContext("2d");
function measureTextHeight(left, top, width, height,text) {
// Draw the text in the specified area
ctx.save();
ctx.clearRect(0,0, canvas.width, canvas.height);
ctx.fillText(text, 0, 100); // This seems like tall text... Doesn't it?
ctx.restore();
// Get the pixel data from the canvas
var data = ctx.getImageData(left, top, width, height).data,
first = false,
last = false,
r = 100,
c = 0;
// Find the first line with a non-white pixel
while(r) {
r--;
for(c = 0; c < width; c++) {
if(data[r * width * 4 + c * 4 + 3]) {
first = r;
break;
}
}
// If we've got it then return the height
if(first != r) return 99 - first;
}
// We screwed something up... What do you expect from free code?
return 0;
}
ctx.baseline = "Alphabetic";
ctx.font= "36px arial";
var height = measureTextHeight(0, 0, canvas.width, canvas.height,text);
//return the height of the string
return height;
} // end $(function(){});
从那里我只需对y进行以下调整即可将文本偏移到中心位置:
var textheight = fontheight(inputtext); //Calculate Text Height
var textheight2 = fontheight2(inputtext); //Calculate portion above the baseline
var difference = textheight - textheight2; // Calculate the portion below the baseline
var y = 100 - difference + textheight/2; // Adjust the y cordinate
这会偏移y以针对文本基线下方的文本部分进行调整。我在这里更新了JSFiddle http://jsfiddle.net/grapien/R6DWN/6/。
答案 1 :(得分:0)
您可以查看此link。使用文本包装器。