Javascript HTML5 canvas ctx.fillText赢得';你不会断线吗?
如果文本包含“\n”,我似乎无法将文本添加到画布。我的意思是,换行符不起作用Javascript HTML5 canvas ctx.fillText赢得';你不会断线吗?,javascript,html,canvas,line,break,Javascript,Html,Canvas,Line,Break,如果文本包含“\n”,我似乎无法将文本添加到画布。我的意思是,换行符不起作用 ctxPaint.fillText("s ome \n \\n <br/> thing", x, y); ctxPaint.fillText(“some\n\\nthing”,x,y); 上面的代码将在一行上绘制“some\nthing” 这是fillText的限制还是我做错了?“\n”在那里,没有打印出来,但也不起作用。我认为这也不可能,但是解决方法是创建一个元素并用Javascript定位它。如果
ctxPaint.fillText("s ome \n \\n <br/> thing", x, y);
ctxPaint.fillText(“some\n\\n
thing”,x,y);
上面的代码将在一行上绘制“some\nthing”
这是fillText的限制还是我做错了?“\n”在那里,没有打印出来,但也不起作用。我认为这也不可能,但是解决方法是创建一个
元素并用Javascript定位它。如果您只想处理文本中的换行符,可以通过在换行符处拆分文本并多次调用fillText()
差不多
var c=document.getElementById('c').getContext('2d');
c、 字体='11px快递';
控制台日志(c);
var txt='第1行\n第2行\n第三行..';
var x=30;
变量y=30;
var线宽=15;
var lines=txt.split('\n');
对于(var i=0;i我担心这是Canvas'fillText
的一个限制。没有多行支持。更糟糕的是,没有内置的方法来测量行高,只有宽度,这让自己更难做到
很多人都编写了自己的多行支持,也许其中最著名的项目是
你需要做的要点是多次调用fillText
,同时每次都将文本的高度添加到y值。(我相信,测量M的宽度是skywriter人员近似文本所做的。)提供的换行代码(在空格处断开)非常有用。
我扩展了他的代码以支持换行符\n
。此外,通常情况下,边界框的尺寸很有用,因此multiMeasureText()
同时返回宽度和高度
您可以在这里看到代码:使用javascript我开发了一个解决方案。它并不漂亮,但对我来说很有效:
函数drawMultilineText(){
//设置上下文和格式
var context=document.getElementById(“画布”).getContext(“2d”);
context.font=fontStyleStr;
context.textAlign=“中心”;
context.textbrealine=“top”;
context.fillStyle=“#000000”;
//准备要绘制为多行文字的textarea值。
var textval=document.getElementByID(“textarea”).value;
var textvalArr=toMultiLine(textval);
var行间距=25;
var startX=0;
var-startY=0;
//在画布上画每一条线。
对于(变量i=0;i 标记拆分值。
函数到多行(文本){
var textArr=新数组();
text=text.replace(/\n\r?/g,
);
textArr=text.split(
);
返回textArr;
}
希望这会有所帮助!我认为您仍然可以依赖CSS
ctx.measureText().height doesn’t exist.
幸运的是,通过CSS hack ardry(有关修复使用CSS度量的旧实现的更多方法,请参见排版度量),我们可以通过测量具有相同字体属性的字体的偏移来找到文本的高度:
var d = document.createElement(”span”);
d.font = “20px arial”
d.textContent = “Hello world!”
var emHeight = d.offsetHeight;
发件人:
参加这个聚会可能有点晚了,但我发现下面关于在画布上包装文本的教程非常完美
从这一点上,我可以考虑使用多行代码(对不起,Ramirez,你的代码对我不起作用!)。我在画布中包装文本的完整代码如下所示:
<script type="text/javascript">
// http: //www.html5canvastutorials.com/tutorials/html5-canvas-wrap-text-tutorial/
function wrapText(context, text, x, y, maxWidth, lineHeight) {
var cars = text.split("\n");
for (var ii = 0; ii < cars.length; ii++) {
var line = "";
var words = cars[ii].split(" ");
for (var n = 0; n < words.length; n++) {
var testLine = line + words[n] + " ";
var metrics = context.measureText(testLine);
var testWidth = metrics.width;
if (testWidth > maxWidth) {
context.fillText(line, x, y);
line = words[n] + " ";
y += lineHeight;
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
y += lineHeight;
}
}
function DrawText() {
var canvas = document.getElementById("c");
var context = canvas.getContext("2d");
context.clearRect(0, 0, 500, 600);
var maxWidth = 400;
var lineHeight = 60;
var x = 20; // (canvas.width - maxWidth) / 2;
var y = 58;
var text = document.getElementById("text").value.toUpperCase();
context.fillStyle = "rgba(255, 0, 0, 1)";
context.fillRect(0, 0, 600, 500);
context.font = "51px 'LeagueGothicRegular'";
context.fillStyle = "#333";
wrapText(context, text, x, y, maxWidth, lineHeight);
}
$(document).ready(function () {
$("#text").keyup(function () {
DrawText();
});
});
</script>
//http://www.html5canvastutorials.com/tutorials/html5-canvas-wrap-text-tutorial/
函数wrapText(上下文、文本、x、y、maxWidth、lineHeight){
var cars=text.split(“\n”);
对于(var ii=0;iimaxWidth){
填充文本(行,x,y);
行=字[n]+“”;
y+=线宽;
}
否则{
直线=测试线;
}
}
填充文本(行,x,y);
y+=线宽;
}
}
函数DrawText(){
var canvas=document.getElementById(“c”);
var context=canvas.getContext(“2d”);
clearRect(0,0500600);
var maxWidth=400;
var-lineHeight=60;
var x=20;/(canvas.width-maxWidth)/2;
变量y=58;
var text=document.getElementById(“text”).value.toUpperCase();
context.fillStyle=“rgba(255,0,0,1)”;
fillRect(0,060500);
context.font=“51px‘Leaguegothicrular’”;
context.fillStyle=“#333”;
wrapText(上下文、文本、x、y、最大宽度、线宽);
}
$(文档).ready(函数(){
$(“#文本”).keyup(函数(){
DrawText();
});
});
其中,c
是我画布的ID,text
是我文本框的ID
正如您可能看到的,我使用的是非标准字体。您可以使用@font-face,只要在操作画布之前在某些文本上使用过该字体,否则画布将无法使用该字体
希望这对其他人有所帮助。Canvas元素不支持换行符“\n”、制表符“\t”或标签等字符
试试看:
var newrow = mheight + 30;
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.font = "bold 24px 'Verdana'";
ctx.textAlign = "center";
ctx.fillText("Game Over", mwidth, mheight); //first line
ctx.fillText("play again", mwidth, newrow); //second line
或者多行:
var textArray = new Array('line2', 'line3', 'line4', 'line5');
var rows = 98;
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.font = "bold 24px 'Verdana'";
ctx.textAlign = "center";
ctx.fillText("Game Over", mwidth, mheight); //first line
for(var i=0; i < textArray.length; ++i) {
rows += 30;
ctx.fillText(textArray[i], mwidth, rows);
}
var textary=new数组('line2','line3','line4','line5');
var行=98;
ctx.fillStyle=“rgb(0,0,0)”;
ctx.font=“bold 24px‘Verdana’”;
ctx.textAlign=“中心”;
fillText(“游戏结束”,mwidth,mheight);//第一行
对于(var i=0;i<
var textArray = new Array('line2', 'line3', 'line4', 'line5');
var rows = 98;
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.font = "bold 24px 'Verdana'";
ctx.textAlign = "center";
ctx.fillText("Game Over", mwidth, mheight); //first line
for(var i=0; i < textArray.length; ++i) {
rows += 30;
ctx.fillText(textArray[i], mwidth, rows);
}
// Library: mltext.js
// Desciption: Extends the CanvasRenderingContext2D that adds two functions: mlFillText and mlStrokeText.
//
// The prototypes are:
//
// function mlFillText(text,x,y,w,h,vAlign,hAlign,lineheight);
// function mlStrokeText(text,x,y,w,h,vAlign,hAlign,lineheight);
//
// Where vAlign can be: "top", "center" or "button"
// And hAlign can be: "left", "center", "right" or "justify"
// Author: Jordi Baylina. (baylina at uniclau.com)
// License: GPL
// Date: 2013-02-21
function mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, fn) {
text = text.replace(/[\n]/g, " \n ");
text = text.replace(/\r/g, "");
var words = text.split(/[ ]+/);
var sp = this.measureText(' ').width;
var lines = [];
var actualline = 0;
var actualsize = 0;
var wo;
lines[actualline] = {};
lines[actualline].Words = [];
i = 0;
while (i < words.length) {
var word = words[i];
if (word == "\n") {
lines[actualline].EndParagraph = true;
actualline++;
actualsize = 0;
lines[actualline] = {};
lines[actualline].Words = [];
i++;
} else {
wo = {};
wo.l = this.measureText(word).width;
if (actualsize === 0) {
while (wo.l > w) {
word = word.slice(0, word.length - 1);
wo.l = this.measureText(word).width;
}
if (word === "") return; // I can't fill a single character
wo.word = word;
lines[actualline].Words.push(wo);
actualsize = wo.l;
if (word != words[i]) {
words[i] = words[i].slice(word.length, words[i].length);
} else {
i++;
}
} else {
if (actualsize + sp + wo.l > w) {
lines[actualline].EndParagraph = false;
actualline++;
actualsize = 0;
lines[actualline] = {};
lines[actualline].Words = [];
} else {
wo.word = word;
lines[actualline].Words.push(wo);
actualsize += sp + wo.l;
i++;
}
}
}
}
if (actualsize === 0) lines[actualline].pop();
lines[actualline].EndParagraph = true;
var totalH = lineheight * lines.length;
while (totalH > h) {
lines.pop();
totalH = lineheight * lines.length;
}
var yy;
if (vAlign == "bottom") {
yy = y + h - totalH + lineheight;
} else if (vAlign == "center") {
yy = y + h / 2 - totalH / 2 + lineheight;
} else {
yy = y + lineheight;
}
var oldTextAlign = this.textAlign;
this.textAlign = "left";
for (var li in lines) {
var totallen = 0;
var xx, usp;
for (wo in lines[li].Words) totallen += lines[li].Words[wo].l;
if (hAlign == "center") {
usp = sp;
xx = x + w / 2 - (totallen + sp * (lines[li].Words.length - 1)) / 2;
} else if ((hAlign == "justify") && (!lines[li].EndParagraph)) {
xx = x;
usp = (w - totallen) / (lines[li].Words.length - 1);
} else if (hAlign == "right") {
xx = x + w - (totallen + sp * (lines[li].Words.length - 1));
usp = sp;
} else { // left
xx = x;
usp = sp;
}
for (wo in lines[li].Words) {
if (fn == "fillText") {
this.fillText(lines[li].Words[wo].word, xx, yy);
} else if (fn == "strokeText") {
this.strokeText(lines[li].Words[wo].word, xx, yy);
}
xx += lines[li].Words[wo].l + usp;
}
yy += lineheight;
}
this.textAlign = oldTextAlign;
}
(function mlInit() {
CanvasRenderingContext2D.prototype.mlFunction = mlFunction;
CanvasRenderingContext2D.prototype.mlFillText = function (text, x, y, w, h, vAlign, hAlign, lineheight) {
this.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, "fillText");
};
CanvasRenderingContext2D.prototype.mlStrokeText = function (text, x, y, w, h, vAlign, hAlign, lineheight) {
this.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, "strokeText");
};
})();
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var T = "This is a very long line line with a CR at the end.\n This is the second line.\nAnd this is the last line.";
var lh = 12;
ctx.lineWidth = 1;
ctx.mlFillText(T, 10, 10, 100, 100, 'top', 'left', lh);
ctx.strokeRect(10, 10, 100, 100);
ctx.mlFillText(T, 110, 10, 100, 100, 'top', 'center', lh);
ctx.strokeRect(110, 10, 100, 100);
ctx.mlFillText(T, 210, 10, 100, 100, 'top', 'right', lh);
ctx.strokeRect(210, 10, 100, 100);
ctx.mlFillText(T, 310, 10, 100, 100, 'top', 'justify', lh);
ctx.strokeRect(310, 10, 100, 100);
ctx.mlFillText(T, 10, 110, 100, 100, 'center', 'left', lh);
ctx.strokeRect(10, 110, 100, 100);
ctx.mlFillText(T, 110, 110, 100, 100, 'center', 'center', lh);
ctx.strokeRect(110, 110, 100, 100);
ctx.mlFillText(T, 210, 110, 100, 100, 'center', 'right', lh);
ctx.strokeRect(210, 110, 100, 100);
ctx.mlFillText(T, 310, 110, 100, 100, 'center', 'justify', lh);
ctx.strokeRect(310, 110, 100, 100);
ctx.mlFillText(T, 10, 210, 100, 100, 'bottom', 'left', lh);
ctx.strokeRect(10, 210, 100, 100);
ctx.mlFillText(T, 110, 210, 100, 100, 'bottom', 'center', lh);
ctx.strokeRect(110, 210, 100, 100);
ctx.mlFillText(T, 210, 210, 100, 100, 'bottom', 'right', lh);
ctx.strokeRect(210, 210, 100, 100);
ctx.mlFillText(T, 310, 210, 100, 100, 'bottom', 'justify', lh);
ctx.strokeRect(310, 210, 100, 100);
ctx.mlStrokeText("Yo can also use mlStrokeText!", 0 , 310 , 420, 30, 'center', 'center', lh);
CanvasRenderingContext2D.prototype.wrapText = function (text, x, y, maxWidth, lineHeight) {
var lines = text.split("\n");
for (var i = 0; i < lines.length; i++) {
var words = lines[i].split(' ');
var line = '';
for (var n = 0; n < words.length; n++) {
var testLine = line + words[n] + ' ';
var metrics = this.measureText(testLine);
var testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
this.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else {
line = testLine;
}
}
this.fillText(line, x, y);
y += lineHeight;
}
}
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
ctx.fillStyle = "black";
ctx.font = "12px sans-serif";
ctx.textBaseline = "top";
ctx.wrapText("Hello\nWorld!",20,20,160,16);
var texts=($(this).find('.noteContent').html()).split("<br>");
for (var k in texts) {
ctx.fillText(texts[k], left, (top+((parseInt(ctx.font)+2)*k)));
}
function fillTextMultiLine(ctx, text, x, y) {
var lineHeight = ctx.measureText("M").width * 1.2;
var lines = text.split("\n");
for (var i = 0; i < lines.length; ++i) {
ctx.fillText(lines[i], x, y);
y += lineHeight;
}
}
var wrapText = function (context, text, x, y, maxWidth, lineHeight) {
var paragraphs = text.split("\n");
var textLines = [];
// Loop through paragraphs
for (var p = 0; p < paragraphs.length; p++) {
var line = "";
var words = paragraphs[p].split(" ");
// Loop through words
for (var w = 0; w < words.length; w++) {
var testLine = line + words[w] + " ";
var metrics = context.measureText(testLine);
var testWidth = metrics.width;
// Make a line break if line is too long
if (testWidth > maxWidth) {
textLines.push(line.trim());
line = words[w] + " ";
}
else {
line = testLine;
}
}
textLines.push(line.trim());
}
// Move text up if centered vertically
if (context.textBaseline === 'middle')
y = y - ((textLines.length-1) * lineHeight) / 2;
// Render text on canvas
for (var tl = 0; tl < textLines.length; tl++) {
context.fillText(textLines[tl], x, y);
y += lineHeight;
}
};
var wrap_text = (ctx, text, x, y, lineHeight, maxWidth, textAlign) => {
if(!textAlign) textAlign = 'center'
ctx.textAlign = textAlign
var words = text.split(' ')
var lines = []
var sliceFrom = 0
for(var i = 0; i < words.length; i++) {
var chunk = words.slice(sliceFrom, i).join(' ')
var last = i === words.length - 1
var bigger = ctx.measureText(chunk).width > maxWidth
if(bigger) {
lines.push(words.slice(sliceFrom, i).join(' '))
sliceFrom = i
}
if(last) {
lines.push(words.slice(sliceFrom, words.length).join(' '))
sliceFrom = i
}
}
var offsetY = 0
var offsetX = 0
if(textAlign === 'center') offsetX = maxWidth / 2
for(var i = 0; i < lines.length; i++) {
ctx.fillText(lines[i], x + offsetX, y + offsetY)
offsetY = offsetY + lineHeight
}
}
ctx.textBaseline="bottom";
ctx.fillText("First line", x-position, y-position);
ctx.textBaseline="top";
ctx.fillText("Second line", x-position, y-position);
npm install canvas-txt --save
ctx.fillText("line1", w,x,y,z)
ctx.fillText("line2", w,x,y,z+20)