我有一个 Canvas ,以及一个位于 Canvas 顶部的文本区域:
<canvas id="ideaBox" width="400" height="400"></canvas>
<textarea id="ideaTextArea" rows="15"></textarea>
我想将框的内容(包括文本区域)捕获到图像中。这可能吗?
我尝试使用:
var MIME_TYPE = "image/png";
var imgURL = canvas.toDataURL(MIME_TYPE);
但它省略了文本,因为文本位于文本区域中,而不是 Canvas 中。
我还尝试使用 html2canvas ( http://html2canvas.hertzen.com/ ),但只能将一个元素传递到脚本中,因此我无法同时传递 Canvas 和文本区域。
有人对此有想法或经验吗?
最佳答案
以下是如何将标题附加到现有 Canvas 的底部:
创建 Canvas 的副本,并将文本区域文本附加到副本中。
- 假设文本必须在原始 Canvas 的宽度范围内换行,则从文本区域计算换行文本的高度(请参阅下面的示例代码)。
- 创建一个新的内存 Canvas 。
将新 Canvas 的大小调整为原始 Canvas 宽度,但原始 Canvas 高度加上换行文本高度。
newCanvas.width=originalCanvas.width; newCanvas.height=originalCanvas.height+wrappedTextHeight;
DrawImage
将原始 Canvas 内容绘制到新 Canvas 上。- 在新 Canvas 的底部绘制换行文本。
- 使用
.toDataURL
从新 Canvas 创建新图像。
示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var text='Now is the time for all good men to come to the aid of their country.'
var fontsize=14;
var fontface='verdana';
// testing: draw something on the canvas
ctx.fillStyle='gold';
ctx.fillRect(0,0,cw,ch);
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(75,270);
ctx.lineTo(100,50);
ctx.lineTo(125,270);
ctx.lineTo(150,50);
ctx.quadraticCurveTo(250,160,150,270);
ctx.lineWidth=15;
ctx.strokeStyle='purple';
ctx.lineCap='round';
ctx.lineJoin='round';
ctx.stroke();
// append a caption at the bottom of the canvas
applyCaption(canvas,text,fontsize,fontface);
function applyCaption(origCanvas,text,fontsize,fontface){
// calc the height of the wrapped text
var height=wrapText(0,0,text,fontsize,fontface,canvas.width-20);
// Create a new canvas
// Resize the new canvas same as original canvas
// but taller by the text height
var c=document.createElement('canvas');
var cctx=c.getContext('2d');
c.width=origCanvas.width;
c.height=origCanvas.height+height;
// draw the original canvas contents to the new canvas
cctx.drawImage(origCanvas,0,0);
// draw the wrapped text at the bottom of the new canvas
cctx.fillStyle='white';
cctx.fillRect(0,c.height-height,c.width,height);
cctx.fillStyle='black';
wrapText(10,c.height-height,text,fontsize,fontface,canvas.width-20,cctx);
// create an image from the new canvas
var img=new Image();
img.onload=function(){
document.body.appendChild(img);
}
img.src=c.toDataURL();
}
function wrapText(x,y,text,fontsize,fontface,maxwidth,context){
if(!context){
// we're just calculating the wrapped text height
// so create a throw-away context to work with
var context=document.createElement('canvas').getContext('2d');
}
var startingY=y;
var words = text.split(' ');
var line = '';
var space='';
var lineHeight = fontsize*1.286;
context.font = fontsize + "px " + fontface;
context.textAlign='left';
context.textBaseline='top'
for (var n=0; n<words.length; n++) {
var testLine = line + space + words[n];
space=' ';
if (context.measureText(testLine).width > maxwidth) {
context.fillText(line,x,y);
line = words[n] + ' ';
y += lineHeight;
space='';
} else {
line = testLine;
}
}
context.fillText(line, x,y);
return(y+lineHeight-startingY);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; }
img{border:1px solid lightgray; }
<h4>Original canvas & New canvas with appended caption</h4>
<canvas id="canvas" width=250 height=300></canvas>
关于javascript - 如何从 Canvas 和文本区域创建图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32257574/