mirror of
https://github.com/wassname/CanvasTextWrapper.git
synced 2026-09-10 11:40:42 +08:00
added sizeToFill option + ui updates
This commit is contained in:
@@ -3,6 +3,7 @@ body {
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
font-family: 'Open Sans', sans-serif;
|
font-family: 'Open Sans', sans-serif;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
line-height: 140%;
|
||||||
}
|
}
|
||||||
|
|
||||||
div, header, footer, article {
|
div, header, footer, article {
|
||||||
@@ -128,9 +129,17 @@ img {
|
|||||||
|
|
||||||
span {
|
span {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span, .emph {
|
span, .emph {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
background: #fff;
|
||||||
|
color: #0D9F69;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|||||||
+26
-15
@@ -76,27 +76,38 @@
|
|||||||
<li>"auto" - text fills the element's width going to a new line on a whole word when no more space</li>
|
<li>"auto" - text fills the element's width going to a new line on a whole word when no more space</li>
|
||||||
<li>"word" - each next word will be placed on a new line</li>
|
<li>"word" - each next word will be placed on a new line</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
|
||||||
NOTE: if a single word is too long to fit the width with specified font size, it will be broken into as
|
|
||||||
many lines as required on any letter without specific word breaking rule.
|
|
||||||
</p>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
<li>
|
||||||
|
<div class="emph">sizeToFill</div>
|
||||||
|
(Boolean) - auto font size to fill text container
|
||||||
|
<ul class="values">
|
||||||
|
<li>"true" - ignore given font size and resize text to fill its padded container</li>
|
||||||
|
<li>"true" - use specified or default font size</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<p>
|
||||||
|
NOTE: if a single word is too long to fit the width with specified font size, it will be broken into as
|
||||||
|
many lines as required on any letter without specific word breaking rule unless <strong>sizeToFill</strong> option is used.
|
||||||
|
</p>
|
||||||
|
</ul><br/>
|
||||||
|
|
||||||
<h2>Defaults</h2><br/>
|
<h2>Defaults</h2><br/>
|
||||||
|
|
||||||
<p>The default options object which values will be used if a property is not specified or no object is passed:</p>
|
<p>The default options object which values will be used if a property is not specified or no object is passed:</p>
|
||||||
|
|
||||||
<p class="white-block">
|
<pre class="white-block">
|
||||||
{ font: "18px Arial, sans-serif",<br/>
|
{
|
||||||
textAlign: "left",<br/>
|
font: "18px Arial, sans-serif",
|
||||||
verticalAlign: "top",<br/>
|
textAlign: "left",
|
||||||
paddingX: 0,<br/>
|
verticalAlign: "top",
|
||||||
paddingY: 0,<br/>
|
paddingX: 0,
|
||||||
fitParent: false,<br/>
|
paddingY: 0,
|
||||||
lineBreak: "auto" }
|
fitParent: false,
|
||||||
</p>
|
lineBreak: "auto",
|
||||||
<br/>
|
sizeToFill: false
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<br/><br/>
|
||||||
|
|
||||||
<h2>Usage</h2><br/>
|
<h2>Usage</h2><br/>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
+44
-16
@@ -1,5 +1,5 @@
|
|||||||
/*! CanvasTextWrapper (https://github.com/namniak/CanvasTextWrapper)
|
/*! CanvasTextWrapper (https://github.com/namniak/CanvasTextWrapper)
|
||||||
* Version: 0.1.0
|
* Version: 0.2.0
|
||||||
*
|
*
|
||||||
* MIT License (http://www.opensource.org/licenses/mit-license.html)
|
* MIT License (http://www.opensource.org/licenses/mit-license.html)
|
||||||
* Copyright (c) 2014 Vadim Namniak
|
* Copyright (c) 2014 Vadim Namniak
|
||||||
@@ -15,10 +15,12 @@
|
|||||||
paddingX: 0, // zero px left & right text padding relative to canvas or parent
|
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
|
paddingY: 0, // zero px top & bottom text padding relative to canvas or parent
|
||||||
fitParent: false, // text is tested to fit canvas width
|
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 (given font size is ignored)
|
||||||
};
|
};
|
||||||
|
|
||||||
window.CanvasTextWrapper = function(canvas, text, opts) {
|
window.CanvasTextWrapper = function(canvas, text, opts) {
|
||||||
|
|
||||||
if (!(this instanceof CanvasTextWrapper)) {
|
if (!(this instanceof CanvasTextWrapper)) {
|
||||||
throw new TypeError('CanvasTextWrapper constructor failed. Use "new" keyword when instantiating.');
|
throw new TypeError('CanvasTextWrapper constructor failed. Use "new" keyword when instantiating.');
|
||||||
}
|
}
|
||||||
@@ -32,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extract font size
|
// extract font size
|
||||||
this.lineHeight = parseInt(this.font.replace(/^\D+/g, ''), 10);
|
this.lineHeight = parseInt(this.font.replace(/^\D+/g, ''), 10) || 18;
|
||||||
|
|
||||||
// validate all set properties
|
// validate all set properties
|
||||||
this.validate();
|
this.validate();
|
||||||
@@ -48,36 +50,59 @@
|
|||||||
CanvasTextWrapper.prototype = {
|
CanvasTextWrapper.prototype = {
|
||||||
|
|
||||||
drawText: function() {
|
drawText: function() {
|
||||||
var canvas = this.canvas;
|
var elementWidth = (this.fitParent === false) ? this.canvas.width : this.canvas.parentNode.clientWidth;
|
||||||
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 textPos = {
|
var textPos = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0
|
y: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
this.checkWordsLength(context, words, maxTextLength);
|
if (this.sizeToFill) {
|
||||||
this.breakTextIntoLines(context, lines, words, maxTextLength);
|
// starting at 1px increase font size by 1px until text block exceeds the height of its padded container or until words break
|
||||||
|
var elementHeight = ((this.fitParent === false) ? this.canvas.height : this.canvas.parentNode.clientHeight) - (this.paddingX * 2);
|
||||||
|
var numWords = this.text.trim().split(/\s+/).length;
|
||||||
|
var fontSize = 0;
|
||||||
|
do {
|
||||||
|
this.setFontSize(++fontSize);
|
||||||
|
var lines = this.getWrappedText(elementWidth);
|
||||||
|
var textBlockHeight = lines.length * this.lineHeight;
|
||||||
|
} while (textBlockHeight < elementHeight && lines.join(' ').split(/\s+/).length == numWords);
|
||||||
|
|
||||||
// height of the broken down into lines text
|
// 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;
|
var textBlockHeight = lines.length * this.lineHeight;
|
||||||
|
|
||||||
// set vertical align for the whole text block
|
// set vertical align for the whole text block
|
||||||
this.setTextVerticalAlign(textPos, textBlockHeight);
|
this.setTextVerticalAlign(textPos, textBlockHeight);
|
||||||
|
|
||||||
for (var i = 0; i < lines.length; i++) {
|
for (var i = 0; i < lines.length; i++) {
|
||||||
this.setTextHorizontalAlign(context, textPos, elementWidth, lines[i]);
|
this.setTextHorizontalAlign(this.context, textPos, elementWidth, lines[i]);
|
||||||
|
|
||||||
textPos.y = parseInt(textPos.y) + parseInt(this.lineHeight);
|
textPos.y = parseInt(textPos.y) + parseInt(this.lineHeight);
|
||||||
context.fillText(lines[i], textPos.x, textPos.y);
|
this.context.fillText(lines[i], textPos.x, textPos.y);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
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.trim().split(/\s+/);
|
||||||
|
var lines = [];
|
||||||
|
|
||||||
|
this.checkWordsLength(this.context, words, maxTextLength);
|
||||||
|
this.breakTextIntoLines(this.context, lines, words, maxTextLength);
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
},
|
||||||
|
|
||||||
checkWordsLength: function(context, words, maxTextLength) {
|
checkWordsLength: function(context, words, maxTextLength) {
|
||||||
for (var i = 0; i < words.length; i++) {
|
for (var i = 0; i < words.length; i++) {
|
||||||
var testString = '';
|
var testString = '';
|
||||||
@@ -166,6 +191,9 @@
|
|||||||
if (this.lineBreak !== 'auto' && this.lineBreak !== 'word') {
|
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".');
|
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.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
+2
-2
@@ -57,8 +57,8 @@ document.onreadystatechange = function() {
|
|||||||
|
|
||||||
// read used properties
|
// read used properties
|
||||||
for (var property in options[i]) {
|
for (var property in options[i]) {
|
||||||
var stringWrapper = (property == 'paddingX' || property == 'paddingY') ? '' : '"';
|
var stringWrapper = (property == 'paddingX' || property == 'paddingY' || property == 'sizeToFill') ? '' : '"';
|
||||||
optionsData += ' <span>' + property + '</span>: ' +
|
optionsData += ' <span>' + property + ':</span> ' +
|
||||||
stringWrapper + options[i][property] + stringWrapper + ',<br/>';
|
stringWrapper + options[i][property] + stringWrapper + ',<br/>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-27
@@ -1,16 +1,11 @@
|
|||||||
(function() {
|
(function() {
|
||||||
window.optionsArr = [
|
window.optionsArr = [
|
||||||
{
|
{
|
||||||
font: 'bold 55px Open Sans, sans-serif',
|
font: 'bold 55px Open Sans, sans-serif'
|
||||||
paddingX: 0,
|
|
||||||
paddingY: 0,
|
|
||||||
fitParent: false,
|
|
||||||
lineBreak: 'auto'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
font: 'normal 40px Open Sans, sans-serif',
|
font: 'normal 40px Impact, Charcoal, sans-serif',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
verticalAlign: 'top',
|
|
||||||
paddingY: 10,
|
paddingY: 10,
|
||||||
lineBreak: 'word'
|
lineBreak: 'word'
|
||||||
},
|
},
|
||||||
@@ -21,34 +16,21 @@
|
|||||||
paddingX: 30
|
paddingX: 30
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
font: 'bold 35px Open Sans, sans-serif',
|
font: 'bold 35px Verdana, Geneva, sans-serif',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
verticalAlign: 'middle'
|
verticalAlign: 'middle'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
font: 'bold 55px Open Sans, sans-serif',
|
font: 'bold 50px Tahoma, Geneva, sans-serif',
|
||||||
textAlign: 'right',
|
textAlign: 'right',
|
||||||
verticalAlign: 'top',
|
paddingX: 25,
|
||||||
paddingX: 15,
|
paddingY: 25
|
||||||
paddingY: 5
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
font: 'bold 45px Open Sans, sans-serif',
|
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
verticalAlign: 'middle',
|
verticalAlign: 'middle',
|
||||||
lineBreak: 'word'
|
//lineBreak: 'word',
|
||||||
},
|
sizeToFill: true
|
||||||
{
|
|
||||||
font: 'bold 25px Open Sans, sans-serif',
|
|
||||||
verticalAlign: 'bottom',
|
|
||||||
paddingX: 10,
|
|
||||||
paddingY: 60
|
|
||||||
},
|
|
||||||
{
|
|
||||||
font: '50px Open Sans, sans-serif',
|
|
||||||
textAlign: 'right',
|
|
||||||
verticalAlign: 'middle',
|
|
||||||
paddingX: 15
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
})();
|
})();
|
||||||
Reference in New Issue
Block a user