2014-09-02 72 views
2

有沒有辦法根據文本行數調整畫布高度?文本將駐留在畫布的底部。圖像也會在畫布的最左上角位置被繪製到畫布的同一時間,因此文本將始終從畫布正下方的固定位置開始。我只想讓畫布根據文本行數進行垂直調整,而不是在輸入文本時,而不是在文本輸入到textarea後單擊按鈕後。HTML 5畫布|根據文本行數調整畫布高度?

我使用這個文本:

... 

var str = $('#TEXTAREA').val(); 

var splittext = $.map(str.split(" "), function (t) { // Split words > than 40 chars 
return t.match(/[\s\S]{1,40}/g) || []; 
}).join(" "); 

qrc.font = 'normal normal 14px monospace'; 
qrc.textAlign = 'center'; 
qrc.fillStyle = '#000'; 

wrapText(qrc, splittext, x, y, maxWidth, lineHeight); 

function wrapText(context, text, x, y, maxWidth, fontSize, fontFace){ 
var words = text.split(' '); 
var line = ''; 
var lineHeight = fontSize; 

context.font=fontSize+" "+fontFace; 

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; 
if(++lineCount>6){return(y);} // Change to "Add 14px to canvas height at each line count" ? 
} 
else { 
line = testLine; 
} 
} 
context.fillText(line, x, y); 
return(y); 
} 

目前,這個代碼不打印的文本超過6行文字。我不知道在代碼中修改/添加的位置(請參閱代碼中的註釋)。任何提示?

UPDATE瓦特/ FIDDLE

這裏的實驗用小提琴。請在你的答案中使用那個小提琴。在小提琴中閱讀TODO評論。我很難過,但我們差不多了! Thx輸入。 http://jsfiddle.net/uL84x7vw/12/

UPDATE瓦特/ FIDDLE

這是小提琴與以前相同,但圖像佔位符代碼移動到的小提琴代碼底部,所以它不會被清除。它看起來更好,但除了文本的最後一行外,所有文本行仍然被清除。顯然有些代碼缺失。 Thx輸入。 http://jsfiddle.net/uL84x7vw/15/

回答

0

更新 - FINAL

DEMO

終於得到了它的工作!文本顯示在圖像佔位符下,並在每次添加或刪除文本行時調整(垂直)畫布大小。拆分功能拆分超過畫布寬度的長單詞(或指定的任何寬度)。使用等寬字體進行固定寬度字符顯示,但您可以嘗試其他類型的字體。 Copying a canvas to image and back救了一天! :

function showCanvas(){ 

var elem = document.getElementById('myCanvas'); 

var wd = 200; 
var ht = 110; 

ctx = elem.getContext('2d'); 
ctx.canvas.width = wd; 
ctx.canvas.height = ht; 
ctx.fillStyle = '#FFF'; // Text area BG color. 
ctx.fillRect(0,0,wd,ht); 

var str = $('#textArea').val(); 
var maxWidth = 190; 
var lineHeight = 14; 
var x = 100; // Since text alignment is centered. 
var y = 104; // Start position of text (under image placeholder). 
var lineCount = 1; 

var splittext = $.map(str.split(" "), function (t) { 
return t.match(/[\s\S]{1,20}/g) || []; 
}).join(" "); 

ctx.font = 'normal normal 14px monospace'; // Monospace fonts have same widths. 
ctx.textAlign = 'center'; // Choose text alignment, change var x accordingly. 
ctx.fillStyle = '#000'; 

wrapText(ctx, splittext, x, y, maxWidth, lineHeight); 

function wrapText(context, text, x, y, maxWidth, fontSize){ 
var words = text.split(' '); 
var line = ''; 
var lineHeight = fontSize; 

context.font=fontSize+" "; 

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; 
if(++lineCount>1){ // If more than one line of text. 

// Start - Canvas copy: 

/* Only use drawImage for copying Canvas contents since getImageData() 
is pixel data extraction requiring more processing time and cpu overhead. */ 

var backCanvas = document.createElement('canvas'); 
backCanvas.width = elem.width; 
backCanvas.height = elem.height; 
var backCtx = backCanvas.getContext('2d'); 
backCtx.drawImage(elem, 0,0); 

// End - Canvas copy. 

elem.height = elem.height+(lineHeight); // Canvas resizes vertically. 
ctx.font = 'normal normal 14px monospace'; 
ctx.textAlign = 'center'; // Choose text alignment, change var x accordingly. 
ctx.fillStyle = '#000'; 

ctx.drawImage(backCanvas, 0,0); // Paste canvas copy into source canvas. 
} 
} 
else { 
line = testLine; 
} 
} 
context.fillText(line, x, y); 
return(y);  
} 

// Create image placeholder. 

ctx.fillStyle = 'red'; 
ctx.fillRect(0,0,200,90); 

} 

如果適用,歡迎對簡化代碼發表評論。 Thx輸入。

0

如果你正在使用jQuery:

var canvas = $('#yourCanvas'); 
canvas.height(canvas.height()+14); 

如果你沒有(和你正在使用height=""屬性):

var canvas = document.getElementById('yourCanvas'); 
canvas.height = canvas.height+14; 

如果您使用的CSS樣式的高度:

var canvas = document.getElementById('yourCanvas'); 
canvas.style.height = (parseInt(canvas.style.height.substring(0,canvas.style.height.length-2))+14)+"px";  
+0

在我的代碼中,我可以實現你的代碼?另外,不需要畫布重繪? Thx輸入。 – koolness 2014-09-03 00:15:57

+0

應該能夠在返回之前(y)做到這一點,在您的評論是 - 這是假設你只需要增加6行後的高度。 根據http://stackoverflow.com/questions/4938346/canvas-width-and-height-in-html5它會清除畫布(並需要重繪),但你也應該手動清除那些瀏覽器的畫布不。 – Jason 2014-09-03 00:26:15

+0

重繪意味着用新參數重複我的功能?我嘗試過,但每次使用它時都會增加高度。我明天會提供一個小提琴進行測試。 Thx輸入。 – koolness 2014-09-03 03:00:10

0

據我所知,您希望您的文本動態顯示並在畫布中調整大小。使用onchange事件來跟蹤文本的行數並動態操作畫布。每次你寫人物時,它已經在畫布上。使用canvas.width = canvas.width + 14;

+0

就像我上面提到的那樣,在輸入時沒有動態應用文本到畫布(我們沒有看到畫布)。只有在點擊一個按鈕後,畫布纔會打印文本。 Thx輸入。 – koolness 2014-09-03 00:18:48

+0

請參閱使用最新的小提琴更新。 Thx輸入。 – koolness 2014-09-03 18:19:46