Added sizeToFill option for resizing text to fill its container

This commit is contained in:
Ian Pearce
2014-10-06 03:00:53 +08:00
parent e5ad6e9e22
commit 60c009b432
3 changed files with 46 additions and 16 deletions
+42 -14
View File
@@ -15,7 +15,8 @@
paddingX: 0, // zero px left & right text padding relative to canvas or parent
paddingY: 0, // zero px top & bottom text padding relative to canvas or parent
fitParent: false, // text is tested to fit canvas width
lineBreak: 'auto' // text fills the element's (canvas or parent) width going to a new line on a whole word
lineBreak: 'auto', // text fills the element's (canvas or parent) width going to a new line on a whole word
sizeToFill: false // text is resized to fill the container height (given font size is ignored)
};
window.CanvasTextWrapper = function(canvas, text, opts) {
@@ -49,24 +50,30 @@
CanvasTextWrapper.prototype = {
drawText: function() {
var canvas = this.canvas;
var context = canvas.getContext('2d');
var elementWidth = (this.fitParent === false) ? canvas.width : canvas.parentNode.clientWidth;
var maxTextLength = elementWidth - (this.paddingX * 2);
var words = this.text.split(/\s+/);
var lines = [];
var elementWidth = (this.fitParent === false) ? this.canvas.width : this.canvas.parentNode.clientWidth;
var textPos = {
x: 0,
y: 0
};
this.checkWordsLength(context, words, maxTextLength);
this.breakTextIntoLines(context, lines, words, maxTextLength);
if (this.sizeToFill) {
// starting at 1px increase font size by 1px until text block exceeds the height of its padded container
var elementHeight = ((this.fitParent === false) ? this.canvas.height : this.canvas.parentNode.clientHeight) - (this.paddingX * 2);
var fontSize = 0;
do {
this.setFontSize(++fontSize);
var lines = this.getWrappedText(elementWidth);
var textBlockHeight = lines.length * this.lineHeight;
} while (textBlockHeight < elementHeight);
// height of the broken down into lines text
var textBlockHeight = lines.length * this.lineHeight;
// use previous font size, not the one that broke the while condition
this.setFontSize(--fontSize);
var lines = this.getWrappedText(elementWidth);
var textBlockHeight = lines.length * this.lineHeight;
} else {
var lines = this.getWrappedText(elementWidth);
var textBlockHeight = lines.length * this.lineHeight;
}
// set vertical align for the whole text block
this.setTextVerticalAlign(textPos, textBlockHeight);
@@ -79,6 +86,24 @@
}
},
setFontSize: function(size) {
var fontParts = this.context.font.split(/\b\d+px\b/i);
this.context.font = fontParts[0] + size + 'px' + fontParts[1];
this.lineHeight = size;
},
getWrappedText: function(elementWidth) {
var maxTextLength = elementWidth - (this.paddingX * 2);
var words = this.text.split(/\s+/);
var lines = [];
this.checkWordsLength(this.context, words, maxTextLength);
this.breakTextIntoLines(this.context, lines, words, maxTextLength);
return lines;
},
checkWordsLength: function(context, words, maxTextLength) {
for (var i = 0; i < words.length; i++) {
var testString = '';
@@ -167,6 +192,9 @@
if (this.lineBreak !== 'auto' && this.lineBreak !== 'word') {
throw new TypeError('From CanvasTextWrapper(): Unsupported line break value is used. Property "lineBreak" can only be set to "auto", or "word".');
}
if (typeof this.sizeToFill !== 'boolean') {
throw new TypeError('From CanvasTextWrapper(): Property "sizeToFill" must be set to a Boolean.');
}
}
};
})();
})();